spring单元测试异常回滚的简单总结
Spring 单元测试回滚总结
目的方法
@Transactional public void insertFooAndThrowException(){ // 先插入 然后抛出异常 mapper.insertFoo(RandomStringUtils.randomAlphanumeric(20)); throw new RuntimeException("Mock throw exception after insert foo"); }
测试类
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = { "classpath:spring/ApplicationContextTest.xml" })public class TransactionRollbackTest{ @Autowired private FooService fooService; @Test public void test_insertFooAndThrowException(){ fooService.insertFooAndThrowException(); }}
1、 目的方法不含事务注解(//@Transactional) 执行过程中抛出异常 此时会插入成功
对应sql为:
2016-06-18T09:26:47.905229Z 33 Query SET autocommit=12016-06-18T09:26:47.939430Z 33 Query select @@session.tx_read_only2016-06-18T09:26:47.939875Z 33 Query insert into foo(a) values('OXrJKEkGCnnyH010ZkTv')
2、 目的方法含事务注解 若执行过程中抛了异常 会自动回滚
2016-06-18T09:19:05.766030Z 31 Query SET autocommit=02016-06-18T09:19:05.829996Z 31 Query select @@session.tx_read_only2016-06-18T09:19:05.830454Z 31 Query insert into foo(a) values('oH2AgMnkrScpf4fGccIo')2016-06-18T09:19:05.831384Z 31 Query rollback
3、 目的方法含事务注解 但测试类显式指定不回滚 如下所示
@TransactionConfiguration(defaultRollback = false)public class TransactionRollbackTest
此时实际仍会回滚
2016-06-18T09:29:51.509882Z 35 Query SET autocommit=02016-06-18T09:29:51.575956Z 35 Query select @@session.tx_read_only2016-06-18T09:29:51.576327Z 35 Query insert into foo(a) values('RN2pujPfOA03MbxIkgjI')2016-06-18T09:29:51.577155Z 35 Query rollback
此种情形 与2类似
4、 目的方法含事务注解 测试类也有事务注解且显式指定不回滚 如下所示
@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=02016-06-18T09:32:42.134612Z 37 Query select @@session.tx_read_only2016-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(:-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)
5、目的方法含事务注解 测试类含事务注解且设置默认回滚
@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=02016-06-18T09:55:15.641818Z 41 Query select @@session.tx_read_only2016-06-18T09:55:15.642228Z 41 Query insert into foo(a) values('1HlH0xmi5bJL01GlEucm')2016-06-18T09:55:15.643248Z 41 Query rollback
关键字:spring, test
版权声明
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处。如若内容有涉嫌抄袭侵权/违法违规/事实不符,请点击 举报 进行投诉反馈!