Obtener transacción de Spring
Una transacción es la unidad más básica de operaciones de una base de datos. Es un conjunto lógico de operaciones que tienen éxito o fracasan. Es una unidad de trabajo indivisible.
Las transacciones tienen 4 características: atomicidad, consistencia, aislamiento y durabilidad, denominadas características ACID.
Ejemplo: transferencia bancaria. Xiao Ming transfiere 100 yuanes a Xiao Hong. Xiao Ming necesita reducir el saldo en 100 y Xiao Hong necesita aumentar el saldo en 100. Estas son dos operaciones que necesitan trabajar juntas para tener éxito. Si se produce una excepción después de que la transferencia de Xiao Ming sea exitosa, el saldo de Xiao Ming se reducirá en 100, pero el saldo de Xiao Hong no aumentará en 100. Esto hará que se pierda dinero. Esto está absolutamente prohibido. El pseudocódigo es el siguiente:
Spring admite 2 métodos de gestión de transacciones.
Spring no administra las transacciones directamente, sino que las administra a través del administrador de transacciones.
Spring proporciona una interfaz PlatformTransactionManager, que se llama administrador de transacciones de Spring. Su código fuente es el siguiente:
El código fuente de esta interfaz es muy simple. Esta interfaz proporciona diferentes clases de implementación para diferentes marcos, de la siguiente manera:
Nota: Estas clases de implementación necesitan importar las dependencias correspondientes para verlas. Hay otros dos objetos en esta interfaz, a saber, TransactionDefinition y TransactionStatus.
La descripción del método es la siguiente:
La descripción del método es la siguiente:
La descripción del método es la siguiente:
Allí es una implementación abstracta predeterminada AbstractTransactionStatus, para TransactionExecution, savepoint y SavepointManager tienen una lógica de implementación específica. El código es demasiado, por lo que no lo publicaré, pero es muy fácil de entender. Hay lógicas de implementación específicas para TransactionExecution, savepoint y SavepointManager. El código es demasiado, así que no lo publicaré, pero es muy fácil de entender. DefaultTransactionStatus hereda AbstractTransactionStatus y continúa expandiéndose.
El comportamiento de propagación de transacciones se refiere a cómo se deben administrar las transacciones durante el proceso cuando se llaman múltiples métodos de transacción. Por ejemplo, cuando el método de transacción A llama al método de transacción B, si el método B se ejecuta en la transacción del método llamador A o inicia una nueva transacción por sí mismo, está determinado por el comportamiento de propagación de la transacción del método de transacción B.
Método de transacción: un método que puede cambiar los datos en la tabla de la base de datos, como agregar, eliminar y modificar datos.
Basándonos en la descripción anterior, podemos dividir los comportamientos en tres categorías principales.
Una característica de las transacciones es el aislamiento y no habrá impacto entre múltiples operaciones de transacción. Sin embargo, si no se considera el aislamiento, se producirán tres problemas de lectura: lectura sucia, lectura no repetible y lectura virtual (fantasma).
Veamos primero qué sucede si no utilizamos transacciones. Cree un paquete llamado aopxml.
Proporcione dos métodos en la clase, uno para que Zhang San aumente la cantidad y otro para que Li Si disminuya la cantidad.
La estructura del proyecto es la siguiente:
Se produjo una excepción en la consola
Al observar los datos de la base de datos, podemos encontrar que la cantidad de Zhang San ha aumentado. pero la cantidad de Li Si no ha disminuido. ¡El banco está llorando! ! ! Entonces necesitamos introducir transacciones Spring para resolver los problemas anteriores.
El administrador de transacciones configurado se implementa como DataSourceTransactionManager, que es la implementación de la interfaz PlatformTransactionManager de JDBC y MBatis.
Configure la notificación de transacciones, especifique el administrador de transacciones que se utilizará y especifique el método de acción de la transacción y los atributos de la transacción.
El valor predeterminado del parámetro de administración de transacciones es transactionManager. Si la identificación del administrador de transacciones es consistente con él, no es necesario especificarlo. El elemento contiene múltiples parámetros de atributos y los atributos de transacción se pueden definir para uno o algunos métodos (métodos especificados por el atributo de nombre), como se muestra en la siguiente tabla:
Como se escribió anteriormente, la gestión de transacciones se realiza en el método de transferencia. No habrá ninguna situación en la que Xiao Ming reduzca el saldo pero Xiao Hong no lo aumente. Si ocurre una excepción, se realiza la reversión.
Al usar anotaciones, no habrá una configuración tan trivial como la anterior. Luego, vuelva a crear el paquete denominado txannon y copie los códigos relacionados con la entidad, el dao y el servicio utilizados en modo xml.
Utilice la anotación EnableTransactionManagement para habilitar transacciones.
Equivalente a la etiqueta tx:annotation-driven.
No es necesario configurar puntos de entrada ni aspectos.
Agregue la anotación @Transactional al método que necesita agregar una transacción, lo que indica que el método requiere administración de transacciones.
La anotación @Transactional se puede agregar a una clase o a un método. Si agrega esta anotación a una clase, todos los métodos de esta clase agregarán transacciones. Si agrega esta anotación a un método, se agregará una transacción a este método.
Transaccional Esta anotación se puede configurar con muchos parámetros relacionados con transacciones.
Ahora que conoce el uso básico, echemos un vistazo al comportamiento de propagación de las transacciones. Esta es una parte difícil de entender en las transacciones Spring porque tiene muchos escenarios.
Si hay una transacción en ejecución, el método actual se ejecutará dentro de esta transacción. De lo contrario, se iniciará una nueva transacción y se ejecutará dentro de su propia transacción.
El método actual debe. se iniciará una nueva transacción y se ejecutará dentro de su propia transacción. Si hay una transacción en ejecución, se debe suspender.
El comportamiento del método de reducción se modifica a Propagation.REQUIRES_NEW. El método de transferencia crea una nueva transacción y luego llama al método de reducción. El método de reducción suspende la transacción del método de transferencia y crea una transacción que pertenece al método de reducción. Entonces, en este ejemplo se crearán dos transacciones. Dado que hay dos transacciones, existen varias situaciones en las que la transacción se puede revertir.
Las operaciones realizadas por el método de transferencia no se revertirán, pero sí las operaciones realizadas por el método de reducción.
Si actualmente hay una transacción (transacción principal), cree una nueva transacción para ejecutarla como una transacción anidada (subtransacción) de la transacción actual; si actualmente no hay ninguna transacción, este valor es equivalente a REQUIRED.
Se produce una excepción en el método de transferencia y se revierte, lo que hará que el método de reducción se revierta al mismo tiempo.
Las operaciones realizadas por el método de transferencia no se revertirán, pero sí las operaciones realizadas por el método de reducción.
Nota: Es necesario detectar el método de transferencia; de lo contrario, se revertirá.
Cuando el método de transacción principal se revierte de forma anormal, la subtransacción se revertirá al mismo tiempo. La subtransacción se puede revertir de forma independiente mediante excepción, sin afectar la transacción principal ni otras subtransacciones (siempre que sea necesario manejar la excepción de la subtransacción)
Si una transacción existe actualmente, unirse a la transacción; si no hay ninguna transacción actualmente, se lanza una excepción.
Dado que el método de transferencia no tiene transacción, se generará una excepción al inicio, de la siguiente manera:
Si hay una transacción en ejecución, el método actual se ejecutará dentro de esta transacción; Actualmente no hay ninguna transacción. Las transacciones se ejecutan de forma no transaccional.
Dado que el método de transferencia no tiene una transacción, el método de reducción no creará una transacción y no se revertirá si ocurre una excepción.
Ejecutar en modo no transaccional Si actualmente existe una transacción, la transacción actual se suspenderá.
El método de transferencia tiene una transacción, pero el comportamiento de propagación del método de reducción es NOT_SUPPORTED, por lo que la transacción del método de transferencia se suspende y el método de reducción se ejecuta de manera no transaccional.
Por lo tanto, en el ejemplo de la imagen, las operaciones realizadas por el método de transferencia se revertirán, pero las operaciones realizadas por el método de reducción no se revertirán.
Se ejecuta en modo no transaccional, generando una excepción si existe una transacción actualmente.
Dado que el método de transferencia tiene una transacción, se generará una excepción al inicio, de la siguiente manera:
Lo anterior siempre ha dicho que se revertirá cuando encuentre una excepción, que Significa que retrocederá cuando encuentre todas las excepciones. No, de forma predeterminada, las transacciones de Spring solo se revertirán cuando encuentren RuntimeException y Error. No se revertirán cuando encuentren excepciones marcadas, como IOException y TimeoutException.
Si desea revertir cuando ocurre una excepción marcada, puede usar el atributo rollbackFor para la siguiente configuración:
De la misma manera, si encuentra una excepción y no desea Para realizar la reversión, utilice el atributo noRollbackFor para configurarlo de la siguiente manera: