Descripción general
La gestión de transacciones es crucial para las aplicaciones empresariales, y puede garantizar la consistencia de los datos incluso si se producen situaciones anormales.
Spring Framework proporciona una abstracción consistente para la gestión de transacciones, con sus características de la siguiente manera:
Proporcione modelos de programación consistentes para diferentes API de transacciones, como JTA (Java Transaction API), JDBC, Hibernate, JPA (Java Persistence API y JDO (Java Data Objects)
Apoya la gestión de transacciones declarativas, especialmente la gestión de transacciones declarativas basadas en anotaciones, que es simple y fácil de usar
Proporciona una API de gestión de transacciones de programación más simple que otras API de transacciones como JTA
Integración perfecta con abstracción de acceso a datos de Spring
Método de gestión de transacciones
Spring admite dos métodos: gestión programática de transacciones y gestión de transacciones declarativas.
Programmatic Transaction Management utiliza TransactionTemplate o utiliza directamente la plataforma subyacente. Para la gestión programática de transacciones, Spring recomienda usar TransactionTemplate.
La gestión de transacciones declarativas se basa en AOP. Su esencia es interceptar el método antes y después, y luego crear o agregar una transacción antes de que comience el método de destino. Después de ejecutar el método de destino, la transacción se envía o retrocede de acuerdo con la situación de ejecución. La mayor ventaja de las transacciones declarativas es que no necesitan administrar las transacciones programáticamente, por lo que no es necesario que el código de gestión de transacciones dopante en el código de lógica de negocios. Simplemente haga declaraciones de reglas de transacción relevantes en el archivo de configuración (o a través de la anotación @Transactional) y puede aplicar reglas de transacción a la lógica comercial.
Obviamente, la gestión de transacciones declarativas es mejor que la gestión de transacciones programáticas, que es exactamente el método de desarrollo no invasivo defendido por Spring. La gestión de transacciones declarativas mantiene el código de negocio libre de contaminación. Un objeto POJO normal puede obtener el soporte completo de transacciones al agregar anotaciones. En comparación con las transacciones de programación, la única desventaja de las transacciones declarativas es que la mejor granularidad de este último solo puede actuar a nivel de método, y no puede lograrse como una transacción programática puede actuar en el nivel de bloque de código. Sin embargo, incluso con tal requisito, hay muchas soluciones, como los bloques de código que requieren que la gestión de transacciones se puede procesar de forma independiente, etc.
También hay dos métodos de uso común para la gestión de transacciones declarativas. Uno es el archivo de configuración XML basado en los espacios de nombres TX y AOP, y el otro se basa en la anotación @Transactional. Obviamente, el método basado en la anotación es más simple y más fácil de usar y más refrescante.
Commit automático (autocommitio) y si se debe enviar automáticamente cuando la conexión está cerrada
Envío automático
Por defecto, la base de datos está en modo de envío automático. Cada declaración está en una transacción separada. Cuando se completa la ejecución de esta declaración, si la ejecución es exitosa, la transacción se presenta implícitamente.
Si la ejecución falla, la transacción se retrocede implícitamente.
Para la gestión normal de transacciones, un conjunto de operaciones relacionadas está en una transacción, por lo que el modo de confirmación automática de la base de datos debe desactivarse. Sin embargo, no tenemos que preocuparnos por esto, Spring establecerá la característica de confirmación automática de la conexión subyacente a False.
org/springframework/jdbc/dataSource/dataSourCetransactionManager.java
// Cambiar a la confirmación manual si es necesario. Esto es muy costoso en algunos controladores JDBC, // por lo que no queremos hacerlo innecesariamente (por ejemplo, si hemos configurado explícitamente // el grupo de conexión para configurarlo ya) .if (con.getAutOcomMit ()) {txObject.setMustResteToutOcommit (verdadero); if (logger.isDebugeNabled ()) {logger.debug ("cambiar la conexión JDBC [" + con + "] para confirmar manual"); } con.setAutOcommit (falso);}Algunos grupos de conexión de datos proporcionan configuraciones para desactivar las confirmaciones de transacciones automáticas, que son mejores para apagar al configurar el grupo de conexión. Sin embargo, C3P0 no proporciona esta característica y solo puede confiar en la primavera para configurarla.
Debido a que la especificación JDBC estipula que cuando se establece el objeto de conexión, debe estar en modo de confirmación automática, que es el valor predeterminado en DBMS, y la confirmación automática debe desactivarse explícitamente si es necesario. C3P0 cumple con esta especificación y permite que el código del cliente establezca explícitamente el modo de envío requerido.
Si enviar automáticamente cuando la conexión está cerrada
Cuando se cierra una conexión, ¿qué debe manejarse si hay una transacción no comprometida? La especificación JDBC no menciona que la política predeterminada de C3P0 es revertir cualquier transacción no comprometida. Esta es la estrategia correcta, pero no hay acuerdo entre los proveedores de conductores de JDBC sobre este tema.
La propiedad AutocommitOnclose de C3P0 es falsa de forma predeterminada, por lo que no es necesario que no la mueva. O puede establecer explícitamente esta propiedad en falso, que será más clara.
Configuración de gestión de transacciones declarativas basada en anotaciones
Spring-Servlet.xml
<
También agregue el espacio de nombres TX en Spring-Servlet.xml
... xmlns: tx = "http://www.springframework.org/schema/tx" xmlns: aop = "http://www.springframework.org/schema/aop" xsi: schemalation http://www.springframework.org/schema/tx/spring-tx.xsd ...
MyBatis participa automáticamente en Spring Transaction Management sin configuración adicional. Mientras la fuente de datos a la que se hace referencia org.mybatis.spring.sqlsessionFactoryBean es consistente con la fuente de datos a la que dataSourCetransactionManager, de lo contrario, la gestión de transacciones no funcionará.
Además, debe descargar el paquete de dependencia AOPALLIANCE.JAR y ponerlo en el directorio web-INF/lib. De lo contrario, se informará una excepción cuando se inicialice la primavera
java.lang.noclassDeffoundError: org/aopalliance/intercept/metodinterceptor
Características de la transacción de primavera
Todas las clases de política de gestión de transacciones en Spring se heredan de org.springframework.transaction.platformtransactionManager interfaz
Public Interface PlatformTransactionManager {TransactionStatus getTransaction (TransactionDefinition Definition) lanza TransactionException; Void Commit (Transactionstatus Status) lanza TransactionException; Void Rollback (Status de transacción Status) lanza TransactionException;}La interfaz TransactionDefinition define las siguientes características:
Nivel de aislamiento de transacciones
El nivel de aislamiento se refiere al grado de aislamiento entre varias transacciones concurrentes. Cinco constantes que representan los niveles de aislamiento se definen en la interfaz de definición de transacciones:
TransactionDefinition.Isolation_Default: Este es el valor predeterminado, lo que indica el nivel de aislamiento predeterminado utilizado para la base de datos subyacente. Para la mayoría de las bases de datos, este valor suele ser TransactionDefinition.Isolation_read_commited.
TransactionDefinition.Isolation_Read_uncommited: Este nivel de aislamiento indica que una transacción puede leer datos modificados por otra transacción pero aún no se ha cometido. Este nivel no previene la lectura sucia, la lectura repetitiva y la lectura fantasma, por lo que rara vez se usa este nivel de aislamiento. Por ejemplo, PostgreSQL en realidad no tiene este nivel.
TransactionDefinition.Isolation_read_commited: este nivel de aislamiento significa que una transacción solo puede leer datos que han sido cometidos por otra transacción. Este nivel evita la lectura sucia, que también es el valor recomendado en la mayoría de los casos.
TransactionDefinition.Isolation_Repeatable_read: este nivel de aislamiento indica que una transacción puede ejecutar una consulta varias veces durante todo el proceso, y los registros devueltos son los mismos cada vez. Este nivel evita lecturas sucias y no repetibles.
TransactionDefinition.Isolation_Serializable: Todas las transacciones se ejecutan una por una en secuencia, por lo que no hay posibilidad de interferencia entre las transacciones, es decir, este nivel puede evitar lectura sucia, lectura no repetible y lectura fantasma. Pero esto afectará seriamente el rendimiento del programa. Este nivel no generalmente se usa.
Comportamiento de comunicación de transacciones
El llamado comportamiento de propagación de la transacción se refiere a que si ya existe un contexto de transacción antes de que se inicie la transacción actual, hay varias opciones que pueden especificar el comportamiento de ejecución de un método transaccional. La definición de definición de transacciones incluye las siguientes constantes que representan el comportamiento de propagación:
TransactionDefinition.Propagation_Required: Si una transacción está actualmente presente, une a la transacción; Si actualmente no hay transacción, cree una nueva transacción. Este es el valor predeterminado.
TransactionDefinition.propagation_requires_new: crea una nueva transacción, y si la transacción existe actualmente, la transacción actual se suspenderá.
TransactionDefinition.Propagation_Supports: une la transacción si actualmente hay una transacción; Si actualmente no hay transacción, continúa ejecutándose de manera no transaccional.
TransactionDefinition.Propagation_Not_Supported: se ejecuta de manera no transaccional, y si actualmente existe una transacción, la transacción actual se suspenderá.
TransactionDefinition.Propagation_Never: se ejecuta de manera no transaccional, lanza una excepción si actualmente está presente una transacción.
TransactionDefinition.Propagation_Mandatory: une la transacción si actualmente hay una transacción; Si actualmente no hay transacción, se lanza una excepción.
TransactionDefinition.Propagation_Nested: si actualmente una transacción está presente, se crea una transacción para ejecutarse como una transacción anidada de la transacción actual; Si no hay transacción, el valor es equivalente a transacciones definition.propagation_required.
Tiempo de espera de la transacción
El llamado tiempo de espera de la transacción se refiere al tiempo máximo permitido por una transacción. Si se excede el límite de tiempo pero la transacción no se ha completado, la transacción se volverá automáticamente. En la definición de transacciones, el tiempo de espera está representado por el valor de INT, y su unidad es de segundos.
La configuración predeterminada es el valor de tiempo de espera del sistema de transacción subyacente. Si el sistema de transacción de base de datos subyacente no establece el valor de tiempo de espera, entonces no es ninguno, y no hay límite de tiempo de espera.
Atributos de solo lectura de transacción
Las transacciones de solo lectura se utilizan en situaciones en las que el código del cliente es de solo lectura pero no modifica los datos. Las transacciones de solo lectura se utilizan en optimización en escenarios específicos, como cuando se usa Hibernate.
El valor predeterminado es las transacciones de lectura y escritura.
Reglas de reversión de la transacción de primavera
La forma recomendada de instruir a Spring Transaction Manager que retroceda una transacción es lanzar una excepción dentro del contexto de la transacción actual. El gerente de transacciones de primavera atrapa cualquier excepción no controlada y luego decide si revolver la transacción que arroja la excepción en función de las reglas.
De manera predeterminada, Spring solo retrocedirá la transacción si la excepción lanzada es una excepción de tiempo de ejecución sin control, es decir, la excepción lanzada es una subclase de RuntimeException (los errores también causarán una reversión de la transacción), mientras que lanzar una excepción verificada no causará retroceso de transacción.
Es posible configurar explícitamente la transacción para retroceder cuando se lanzan esas excepciones, incluidas las excepciones verificadas. También es posible definir claramente aquellas transacciones que no retroceden cuando se arrojan excepciones.
También puede usar mediante programación el método setRollbackOnly () para indicar que una transacción debe ser retrocedida. Lo único que puede hacer después de llamar a SetRollbackonly () es Rollback.
@Anotación transaccional
@Propiedades transaccionales
| propiedad | tipo | describir |
|---|---|---|
| valor | Cadena | Descriptor de calificador opcional, especificando el administrador de transacciones para usar |
| propagación | Enum: propagación | Configuración de comportamiento de propagación de transacciones opcional |
| aislamiento | Enum: aislamiento | Configuración de nivel de aislamiento de transacción opcional |
| readonamente | booleano | Leer y escribir transacciones de solo lectura, Leer y escribir por defecto |
| se acabó el tiempo | int (en segundos granularidad) | Configuración de tiempo de espera de transacción |
| reversión | La matriz de objetos de clase debe ser heredada de lanzamiento | Variedad de clases de excepción que causan retroceso de transacción |
| RollbackforClassName | La matriz de nombres de clase debe ser heredado de Throwable | Matriz de nombres de clase de excepción que causan retroceso de transacción |
| norollbackfor | La matriz de objetos de clase debe ser heredada de lanzamiento | Una matriz de clase de excepción que no causa reversiones de transacción |
| NorollbackforClassName | La matriz de nombres de clase debe ser heredado de Throwable | Una variedad de nombres de clase de excepción que no causarán retroceso de transacción |
uso
@Transactional puede actuar sobre interfaces, métodos de interfaz, clases y métodos de clase. Al actuar en una clase, todos los métodos públicos de la clase tendrán propiedades de transacción de ese tipo. Al mismo tiempo, también podemos usar esta anotación en el nivel de método para anular la definición de nivel de clase.
Aunque la anotación @Transactional se puede aplicar a interfaces, métodos de interfaz, clases y métodos de clase, Spring recomienda no usar esta anotación en interfaces o métodos de interfaz, porque esto solo entrará en vigencia cuando se usa un proxy basado en la interfaz. Además, la anotación @Transactional solo debe aplicarse al método público, que está determinado por la naturaleza de Spring AOP. Si usa la anotación @Transactional en métodos de visibilidad protegidos, privados o predeterminados, esto se ignorará y no se lanzarán excepciones.
Por defecto, solo las llamadas de método desde el exterior serán capturadas por el proxy AOP, es decir, llamar a otros métodos dentro de esta clase dentro de la clase no causará comportamiento de transacción, incluso si el método llamado se modifica utilizando la anotación @Transactional.
@Transactional (readOnly = true) public class DefaultFooService implementa Fooservice {public foo getFoo (string fooname) {// haz algo} // Estas configuraciones tienen precedencia para este método // el atributo de anotación en el método anulará el mismo atributo en la clase annotation @transactional (readonly = false, propagation.requires. updateFoo (foo foo) {// haz algo}}Resumir
Lo anterior es todo el contenido de la interpretación de este artículo sobre el uso de la anotación @Transactional en primavera, y espero que sea útil para todos. Los amigos interesados pueden continuar referiéndose a otros temas relacionados en este sitio. Si hay alguna deficiencia, deje un mensaje para señalarlo. ¡Gracias amigos por su apoyo para este sitio!