Spring 單元測試回滾總結java
目的方法spring
@Transactional public void insertFooAndThrowException(){ // 先插入 而後拋出異常 mapper.insertFoo(RandomStringUtils.randomAlphanumeric(20)); throw new RuntimeException("Mock throw exception after insert foo"); }
測試類sql
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:spring/ApplicationContextTest.xml" }) public class TransactionRollbackTest{ @Autowired private FooService fooService; @Test public void test_insertFooAndThrowException(){ fooService.insertFooAndThrowException(); } }
一、 目的方法不含事務註解(//@Transactional
) 執行過程當中拋出異常 此時會插入成功session
對應sql爲:app
2016-06-18T09:26:47.905229Z 33 Query SET autocommit=1 2016-06-18T09:26:47.939430Z 33 Query select @@session.tx_read_only 2016-06-18T09:26:47.939875Z 33 Query insert into foo(a) values('OXrJKEkGCnnyH010ZkTv')
二、 目的方法含事務註解 若執行過程當中拋了異常 會自動回滾dom
2016-06-18T09:19:05.766030Z 31 Query SET autocommit=0 2016-06-18T09:19:05.829996Z 31 Query select @@session.tx_read_only 2016-06-18T09:19:05.830454Z 31 Query insert into foo(a) values('oH2AgMnkrScpf4fGccIo') 2016-06-18T09:19:05.831384Z 31 Query rollback
三、 目的方法含事務註解 但測試類顯式指定不回滾 以下所示單元測試
@TransactionConfiguration(defaultRollback = false) public class TransactionRollbackTest
此時實際仍會回滾測試
2016-06-18T09:29:51.509882Z 35 Query SET autocommit=0 2016-06-18T09:29:51.575956Z 35 Query select @@session.tx_read_only 2016-06-18T09:29:51.576327Z 35 Query insert into foo(a) values('RN2pujPfOA03MbxIkgjI') 2016-06-18T09:29:51.577155Z 35 Query rollback
此種情形 與2相似lua
四、 目的方法含事務註解 測試類也有事務註解且顯式指定不回滾 以下所示spa
@Transactional @TransactionConfiguration(defaultRollback = false) public class TransactionRollbackTest
執行測試 會有以下的異常
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:720) at org.springframework.test.context.transaction.TransactionalTestExecutionListener$TransactionContext.endTransaction(TransactionalTestExecutionListener.java:597)
但實際仍會回滾
2016-06-18T09:32:42.072941Z 37 Query SET autocommit=0 2016-06-18T09:32:42.134612Z 37 Query select @@session.tx_read_only 2016-06-18T09:32:42.135024Z 37 Query insert into foo(a) values('SeLtrEiQdkTRmcnjNNAy') 2016-06-18T09:32:42.136505Z 37 Query rollback
下面代碼處加上斷點 比較調用鏈
doRollback:284, DataSourceTransactionManager (org.springframework.jdbc.datasource)
僅在目的方法中有事務註解 測試類無事務註解
at org.springframework.jdbc.datasource.DataSourceTransactionManager.doRollback(DataSourceTransactionManager.java:284) at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:849) at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:826) at org.springframework.transaction.interceptor.TransactionAspectSupport.completeTransactionAfterThrowing(TransactionAspectSupport.java:496) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:266) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644) at com.foo.service.FooService$$EnhancerBySpringCGLIB$$58f57234.insertFooAndThrowException(<generated>:-1) at com.foo.service.TransactionRollbackTest.test_insertFooAndThrowException(TransactionRollbackTest.java:26)
目的方法與測試類均有事務註解
at org.springframework.jdbc.datasource.DataSourceTransactionManager.doRollback(DataSourceTransactionManager.java:284) at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:849) at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:716) at org.springframework.test.context.transaction.TransactionalTestExecutionListener$TransactionContext.endTransaction(TransactionalTestExecutionListener.java:597) at org.springframework.test.context.transaction.TransactionalTestExecutionListener.endTransaction(TransactionalTestExecutionListener.java:296) at org.springframework.test.context.transaction.TransactionalTestExecutionListener.afterTestMethod(TransactionalTestExecutionListener.java:189) at org.springframework.test.context.TestContextManager.afterTestMethod(TestContextManager.java:416) at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:91)
五、目的方法含事務註解 測試類含事務註解且設置默認回滾
@Transactional @TransactionConfiguration(defaultRollback = true) public class TransactionRollbackTest
沒有上述異常 且多了以下的日誌輸出
016-06-18 17:55:15,644 - org.springframework.test.context.transaction.TransactionalTestExecutionListener -2126 [main] INFO - Rolled back transaction after test execution for test context [DefaultTestContext@3310ce7b testClass = TransactionRollbackTest, testInstance = com.foo.service.TransactionRollbackTest@1464076e, testMethod = test_insertFooAndThrowException@TransactionRollbackTest, testException = java.lang.RuntimeException: Mock throw exception after insert foo, mergedContextConfiguration = [MergedContextConfiguration@3323d137 testClass = TransactionRollbackTest, locations = '{classpath:spring/ApplicationContextTest.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]
sql爲
2016-06-18T09:55:15.578650Z 41 Query SET autocommit=0 2016-06-18T09:55:15.641818Z 41 Query select @@session.tx_read_only 2016-06-18T09:55:15.642228Z 41 Query insert into foo(a) values('1HlH0xmi5bJL01GlEucm') 2016-06-18T09:55:15.643248Z 41 Query rollback