1. Principios básicos de las transacciones
La esencia de las transacciones de primavera es en realidad el soporte de la base de datos para las transacciones. Sin soporte de transacciones de la base de datos, Spring no puede proporcionar funciones de transacción. Para bases de datos operativas JDBC puras, si desea usar transacciones, puede seguir los siguientes pasos:
1. Obtenga la conexión Connection con = drivermanager.getConnection ()
2. Abra la transacción con.setAutOcommit (verdadero/falso);
3. Ejecutar crud
4. Commit Transaction / Rollback Transaction Con.commit () / Con.Rollback ();
5. Cierre la conexión conn.close ();
Después de usar la función de gestión de transacciones de Spring, ya no podemos escribir el código en los pasos 2 y 4, sino que SIGNG lo realizará automáticamente. Entonces, ¿cómo abre y cierre las transacciones antes y después del crud que escribimos? Al resolver este problema, podemos comprender el principio de implementación de la gestión de transacciones de Spring desde un todo. Permítanme presentar brevemente el método de anotación como ejemplo
1. Encienda el controlador de anotación en el archivo de configuración e identifica anotando el @Transactional en las clases y métodos relevantes.
2. Cuando comience la primavera, analizará y generará frijoles relacionados. En este momento, verificará las clases y métodos con anotaciones relevantes, y generará un proxy para estas clases y métodos, y realizará la inyección de configuración relacionada en función de los parámetros relevantes de @Transaction, de modo que las transacciones relevantes se procesen para nosotros en el proxy (transacciones normales de inicio y transacciones de reversión de excepción).
3. La confirmación de transacción y la reversión de la capa de base de datos real se implementan a través de binlog o registro de rehacer.
2. Propiedades de propagación de las transacciones de primavera
El llamado atributo de propagación de las transacciones de resorte define cómo la primavera debe manejar el comportamiento de múltiples transacciones cuando existen al mismo tiempo. Estas propiedades se definen en la definición de transacciones. Las constantes específicas se explican en la siguiente tabla:
Iii. Nivel de aislamiento de la base de datos
Lectura sucia: una transacción agrega, elimina y modifica los datos, pero no se compromete, y otra transacción puede leer datos no comprometidos. Si la primera transacción regresa en este momento, la segunda transacción lee datos sucios.
No hay lectura repetitiva: dos operaciones de lectura ocurren en una transacción. Entre la primera operación de lectura y la segunda operación, la otra transacción modifica los datos. En este momento, los datos leídos dos veces son inconsistentes.
Lectura de fantasía: la primera transacción modifica los datos en un cierto rango en lotes, y la segunda transacción agrega un datos a este rango. En este momento, la primera transacción perderá la modificación de los datos recién agregados.
Resumir :
Cuanto mayor sea el nivel de aislamiento, más puede garantizar la integridad y consistencia de los datos, pero mayor será el impacto en el rendimiento de la concurrencia.
Se lee el nivel de aislamiento predeterminado de la mayoría de las bases de datos, como SQLServer y Oracle
El nivel de aislamiento predeterminado de algunas bases de datos es: lectura repetible, por ejemplo: mysql innodb
IV. Nivel de aislamiento en primavera
V. Anidación de transacciones
A través del conocimiento teórico anterior, entendemos aproximadamente algunos atributos y características de las transacciones de bases de datos y las transacciones de resorte. A continuación, analizamos algunos escenarios de transacción anidados para comprender profundamente el mecanismo de propagación de transacciones de primavera.
Suponga que el método A () del servicio de transacción externa A llama al método B () del servicio interno B
Propagation_required (Spring Default)
Si el nivel de transacción de serviciob.methodb () se define como propagation_required, entonces cuando se ejecuta el servicio.methoda (), la transacción ya ha comenzado en la primavera. En este momento, se llama ServiceB.Methodb (). ServiceB.Methodb () ve que se está ejecutando dentro de la transacción de ServiceA.Methoda (), y no se inicia una nueva transacción.
Si ServiceB.Methodb () se está ejecutando, se asignará una transacción a sí misma.
De esta manera, si se produce una excepción en ServiceA.Methoda () o en cualquier lugar dentro de ServiceB.Methodb (), la transacción se retirará hacia atrás.
Propagation_requires_new
Por ejemplo, diseñamos que ServiceA.Methoda () tiene un nivel de transacción de propagation_required, y ServiceB.Methodb () tiene un nivel de transacción de propagation_requires_new.
Luego, cuando se ejecuta ServiceB.Methodb (), se suspenderá la transacción donde se encuentra ServiceA.Methoda (), y ServiceB.Methodb () iniciará una nueva transacción y continuará ejecutándose después de que se complete la transacción ServiceB.Methodb ().
La diferencia entre sus transacciones y propagación_required es el grado de reversión de la transacción. Porque ServiceB.Methodb () es una nueva transacción, entonces hay dos transacciones diferentes. Si se ha enviado el servicioB.Methodb (), entonces ServiceA.Methoda () no puede revertir, ServiceB.Methodb () no revertirá. Si ServiceB.Methodb () no puede revertir, si la excepción lanzada por ServiceA.Methoda () se atrapa, la transacción ServiceA.Methoda () aún se puede enviar (principalmente depende de si la excepción lanzada por B es una excepción que A V voluntará).
Propagation_supports
Suponiendo que el nivel de transacción de ServiceB.Methodb () es Propagation_Supports, cuando se ejecuta a ServiceB.Methodb (), si se encuentra que ServiceA.Methoda () ha abierto una transacción, se unirá a la transacción actual. Si se encuentra que ServiceA.Methoda () no ha iniciado la transacción, no comenzará la transacción en sí. En este momento, la transaccionalidad del método interno depende completamente de la transacción más externa.
Propagation_nested
La situación se está volviendo más complicada ahora. La propiedad de transacción de ServiceB.Methodb () está configurada como Propagation_Nested. ¿Cómo cooperarán los dos en este momento? ServiceB#MethodB Si Rollback, entonces las transacciones internas (es decir, ServiceB#Methodb) volverán a SavePoint antes de que se ejecute, mientras que las transacciones externas (es decir, ServiceA#Methoda) pueden tener las siguientes dos formas de manejo:
a. Capturar excepciones y ejecutar la lógica de la rama de excepción
void MethodA () {try {ServiceB.Methodb (); } catch (SomeException) {// ejecutar otros negocios, como ServiceC.Methodc (); }} Este método también es lo más valioso de las transacciones anidadas. Desempeña el papel de la ejecución de la sucursal. Si ServiceB.Methodb falla, entonces ServiceC.Methodc () se ejecuta, y ServiceB.Methodb se ha vuelto de regreso al punto de guardado antes de que se ejecute, por lo que no se generan datos sucios (equivalente a este método que nunca se ejecuta). Esta característica se puede utilizar en algunos servicios especiales, y ni propagation_required ni propagation_requires_new pueden hacer esto.
b. El código de reversión/confirmación de transacciones externas no realiza ninguna modificación. Si la transacción interna (ServiceB#Methodb) Rollback, entonces ServiceB.MethodB vuelve al punto de guardado antes de que se ejecute (en cualquier caso), y la transacción externa (es decir, ServiceA#Methoda) decidirá si se confirma o reversa en función de la configuración específica.
Los otros tres atributos de propagación de transacciones son básicamente ineficaces, por lo que no se realiza ningún análisis aquí.
6. Resumen
Para los lugares donde se necesitan transacciones en el proyecto, sugiero que los desarrolladores deben usar la interfaz TransactionCallback de Spring para implementar transacciones. No use a ciegas anotaciones de transacción de primavera. Si debe usar anotaciones, debe tener una comprensión detallada del mecanismo de propagación y el nivel de aislamiento de las transacciones de primavera, de lo contrario pueden ocurrir efectos inesperados.