1. Cuando mybatis se usa solo, use SQLSession para manejar las transacciones:
clase pública mybatistxtest {private sqlsessionFactory sqlsessionFactory; Lector de lector estático privado; @Beforeclass public static void setupBeForecLass () lanza la excepción {try {reader = recursos.getResourCeaseReader ("Configuration.xml"); sqlSessionFactory = new SqlSessionFactoryBuilder (). Build (Reader); } finalmente {if (lector! = null) {lector.close (); }}} @Test public void updateUsertXtest () {sqlsession session = sqlsessionFactory.opensession (falso); // Abra la sesión y la transacción comienza a prueba {iUsermapper mapper = session.getMapper (iusermapper.class); Usuario user = nuevo usuario (9, "transacción de prueba"); int afectado = mapper.updateuser (usuario); // La declaración de confirmación no se ejecutó debido a la posterior excepción user usuario = nuevo usuario (10, "transacción de prueba continuamente"); int afectado2 = mapper.updateuser (user2); // La declaración de confirmación int i = 2 /0 no se ejecuta debido a la excepción posterior; // La excepción de tiempo de ejecución se desencadena session.commit (); // Enviar la sesión, es decir, el confirmación de transacción} finalmente {session.close (); // Cierre la sesión y la liberación de recursos}}}
2. Después de integrarse con Spring, use la gestión de transacciones de Spring:
Una de las principales razones para usar MyBatis-Spring es que permite que MyBatis participe en la gestión de transacciones de Spring. En lugar de crear un nuevo administrador de transacciones específico para MyBatis, MyBatis-Spring utiliza el DataSourCetransactionManager que existe en primavera.
Una vez que se configura DataSourCetransactionManager, puede configurar las transacciones en Spring como lo hace normalmente. Se admiten la anotación transaccional y la configuración de estilo AOP. Durante el procesamiento de transacciones, se creará y utilizará un objeto SQLSession separado. Cuando se complete la transacción, esta sesión se comprometerá o retrocedirá de la manera apropiada.
Una vez que se crea la transacción, MyBatis-Spring administrará transparentemente las transacciones. No hay necesidad de código adicional en su DAO o clase de servicio.
1. Configuración estándar
Para habilitar el procesamiento de transacciones de Spring, simplemente cree un objeto DataSourCetransactionManager en el archivo de configuración XML de Spring:
<bean id = "transaccionManager"> <Property name = "DataSource" ref = "dataSource"/> </bean>
La fuente de datos especificada generalmente puede ser cualquier fuente de datos JDBC que use Spring. Esto incluye el grupo de conexión y la fuente de datos obtenida a través de la búsqueda JNDI.
Tenga en cuenta que la fuente de datos especificada para el administrador de transacciones debe ser la misma fuente de datos que la utilizada para crear el SQLSessionFactoryBean, de lo contrario, el administrador de transacciones no funcionará.
2. Transacciones de gestión de contenedores
Si está utilizando un contenedor JEE y desea que Spring participe en las transacciones de gestión de contenedores, Spring debe configurarse utilizando JTATRANSACTIONSManager o su subclase especificada por contenedor. La forma más conveniente de hacerlo es usar el espacio de nombres de transacciones de Spring:
<tx: JTA-Transaction-Manager/>
En esta configuración, MyBatis será lo mismo que otros recursos de transacción de Spring configurados por transacciones de gestión de contenedores. Spring usará automáticamente cualquier transacción de contenedor existente, lo que le otorgue una SQLSession. Si no se inicia la transacción, o si se requiere la transacción, Spring habilitará un nuevo contenedor para administrar las transacciones.
Tenga en cuenta que si desea administrar transacciones utilizando contenedores y no la gestión de transacciones de Spring, debe configurar SQLSessionFactoryBean para usar el mybatis managedtransactionFactory básico en lugar de cualquier otro administrador de transacciones de primavera:
<bean id = "sqlsessionFactory"> <Property name = "dataSource" ref = "dataSource"/> <Property name = "TransActionFactoryClass"> <valor> org.apache.ibatis.transaction.Maned.ManagedTransactionFactory "/> </Property> </ // ////> </aube>
3. Gestión de transacciones de programación
SQLSession de MyBatis proporciona un método especificado para manejar transacciones programáticas. Pero cuando se usa MyBatis-Spring, el frijol se inyectará utilizando SQLSession o mapeador administrado por el resorte. Eso significa que la primavera generalmente maneja las transacciones. No puede llamar a los métodos sqlsession.commit (), sqlsession.rollback () o sqlsession.close () en sqlsession administrado por primavera. Si hace esto, se lanzará una Operación no compatible. Tenga en cuenta que no se puede acceder a esos métodos cuando se usan mapeadores inyectados. Independientemente de si la conexión está configurada para autocomitar o no, la ejecución del método de datos SQLSession o cualquier llamada al método mapeador fuera de la transacción Spring se cometirá automáticamente. Aquí hay un ejemplo de una transacción de programación:
DefaultTransactionDefinition def = new DefaultTransactionDefinition (); Def.setPropagationBehavior (transaccionDefinition.propagation_required); TransactionStatus status = txManager.getTransaction (def); intente {usermapper.insertuser (usuario); } Catch (MyException ex) {tirar ex; } txManager.commit (status);4.@Método transaccional:
Cree el archivo Beans-Da-Tx.xml en ClassPath y agregue la configuración de la transacción basada en Beans-Da.xml (Serie V):
<!-- Transaction Manager--> <bean id="txManager" > <property name="dataSource" ref="dataSource" /> </bean> <!-- Transaction annotation driver, classes and methods marked @Transactional will be transactional--> <tx:annotation-driven transaction-manager="txManager" /> <bean id="userService" />
Categoría de servicio:
@Service ("UserService") Public Class UserService {@aUtowired IUSERMAPPER MAPPER; public int BatchUpdateUsersWhenException () {// Usuario no transaccional de usuario = nuevo usuario (9, "antes de la excepción"); int afectado = mapper.updateuser (usuario); // Ejecución Usuario exitoso de usuario2 = nuevo usuario (10, "después de la excepción"); int i = 1/0; // Lanzar excepción de tiempo de ejecución int afectado2 = mapper.updateuser (user2); // no ejecutado if (afectado == 1 && afectadoCount2 == 1) {return 1; } return 0; } @Transactional public int txupDateUsersWhenException () {// user de usuario transaccional = nuevo usuario (9, "antes de excepción"); int afectado = mapper.updateuser (usuario); // reversión debido a la posterior excepción user user2 = nuevo usuario (10, "después de la excepción"); int i = 1/0; // arrojar una excepción de tiempo de ejecución y la reversión de la transacción int afectado2 = mappper.updateuser (user2); // no ejecutado if (afectado == 1 && afectadoCount2 == 1) {return 1; } return 0; }}En la clase de prueba:
@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (ubicaciones = {"classpath: beans-da-tx.xml"}) clase pública SpringIntegRETETTXTest {@Resource Userservice UserService; @Test public void updateUsersExceptionTest () {Userservice.BatchUpDateUsersWhenException (); } @Test public void txupdateUsersExceptionTest () {Userservice.txupdateUsersWhenException (); }}
5. Método de plantilla de transacción
Agregue frijoles-da-tx.xml:
<bean id = "txtemplate"> <constructor-arg type = "org.springframework.transaction.platformtransactionManager" ref = "transaccionManager" /> < /bean>
Únase a la clase UserService:
@AUTOWIRED (requerido = falso) TransactionTemplate txtEmplate; public int tXUPDateUsersWhenExceptionViatxtEmplate () {int retval = txtemplate.Execute (new TransActionCallback <Integer> () {@Override Public Integer doIntransaction (status de transaccionStatus) {// operación de transacción usuarios = nuevo usuario (9, "antes de excepción"); int afectado El usuario de la excepción posterior2 = NUEVO USUARIO (10, "After Exception"); Return Returnval; }Agregue a la clase SpringIngateTxtest:
@Test public void UpdateUsersWhenExceptionViatxtEmplateTest () {Userservice.txupdateUsersWhenExceptionViatxtEmplate (); //}Nota: No puedo atrapar la excepción o RuntimeException sin tirar:
@Transactional Public int tXUPDateUsersWhenExceptionAndCatch () {// Operación transaccional, pero el marco periférico no puede captar la excepción y enviarla si la ejecución es correcta. intente {usuario user = nuevo usuario (9, "antes de la excepción"); int afectado = mapper.updateuser (usuario); // La ejecución fue un usuario exitoso user2 = nuevo usuario (10, "después de la excepción"); int i = 1/0; // Lanzar excepción de tiempo de ejecución int afectado2 = mapper.updateuser (user2); // no ejecutado if (afectado == 1 && afectadoCount2 == 1) {return 1; }} Catch (Exception e) {// Todas las excepciones se capturan sin lanzar E.PrintStackTrace (); } return 0; }