(转载)spring错误抛出触发事务回滚策略
(转载)spring异常抛出触发事务回滚策略Spring、EJB的声明式事务默认情况下都是在抛出unchecked exception后
(转载)spring异常抛出触发事务回滚策略
Spring、EJB的声明式事务默认情况下都是在抛出unchecked exception后才会触发事务的回滚?
测试用业务逻辑方法:?
Java代码??
- /**?
- ?*?如果在spring事务配置中不为切入点(如这里的切入点可以定义成test*)配置事务在什么情况下回滚(格式:-引起回滚的异常类型)?
- ?*?则spring默认只会在service方法抛出unchecked?exception才会触发回滚?
- ?*/??
- public?class?TestServiceImpl?extends?Service?implements?TestService?{??
- ??
- ????/**?
- ?????*?测试spring异常触发事务回滚的service方法?
- ?????*/??
- ????public?void?testAddPerson(String?name)?throws?Exception?{??
- ????????TestPerson?p?=?new?TestPerson();??
- ????????p.setName(name);??
- ????????this.getHibernateGenericController().save(p);??
- ??????????
- ????????/*?
- ?????????*?制造RuntimeException?
- ?????????*?在spring默认的异常回滚策略下,该异常的抛出会触发事务的回滚,数据不会被插入?
- ?????????*/??
- ????????throw?new?RuntimeException("抛出个运行时异常");??
- ??????????
- ????????/**?
- ?????????*?同样是unchecked?exception,spring默认的异常回滚策略下Error的抛出也会触发事务的回滚,数据不会被插入?
- ?????????*/??
- //??????throw?new?Error();??
- ??????????
- ????????/**?
- ?????????*?即使是在spring默认的异常触发事务回滚策略(unchecked?exception触发回滚)下,?
- ?????????*?如果使用try-catch捕获抛出的unchecked异常后没有在catch块中采用页面硬编码的方式使用spring?api对事务做显式的回滚,则事务不会回滚,数据被插入?
- ?????????*?“将异常捕获,并且在catch块中不对事务做显式提交=生吞掉异常”?
- ?????????*/??
- //??????try?{??
- //??????????throw?new?RuntimeException("这个抛出的运行时异常会被try-catch捕获");??
- //??????}?catch(Exception?e)?{??
- //??????????System.out.println("捕获到异常:?"?+?e.getMessage());??
- //??????}??
- ??????????
- ????????/**?
- ?????????*?因为Exception类是个checked?exception,所以这里抛出的异常不会触发事务的回滚,数据被插入?
- ?????????*/??
- //??????throw?new?Exception("a?Exception?instance");??
- ??????????
- ????????/**?
- ?????????*?该BaseException继承自Exception,也为checked?exception,抛出它后:?
- ?????????*?spring默认的回滚策略下,事务未回滚,?数据被插入;?
- ?????????*?在TransactionProxyFactoryBean的transactionAttributes中配置?
- ????????????????????<prop?key="test*">?
- ????????????????????????...?...,-BaseException?
- ????????????????????</prop>?
- ????????????后,事务回滚,数据未被插入?
- ?????????*/??
- //??????throw?new?BaseException("一个BaseException");??
- ????}??
- ??
- }??
关于TransactionProxyFactoryBean的transactionAttributes中字符串的值(定义自TransactionAttributeEditor):?
is a transaction attribute descriptors that parsed via TransactionAttributeEditor?
见本博客:http://wuaner.iteye.com/admin/blogs/567792?
单元测试代码:?
Java代码??
- public?class?TestSpringDefaultRollback?extends?TestCase?{??
- ??
- ????private?static?ApplicationContext?context?=?new?ClassPathXmlApplicationContext("resource/xxx/applicationContext.xml");??
- ????public?void?testDefaultRollback()?throws?Exception{??
- ????????TestService?testServiceImpl?=?(TestService)context.getBean("testService");??
- ????????testServiceImpl.testAddPerson("张三");??
- ????}??
- }??
将异常捕获,并且在catch块中不对事务做显式提交(或其他应该做的操作如关闭资源等)=生吞掉异常?
spring的事务边界是在调用业务方法之前开始的,业务方法执行完毕之后来执行commit or rollback(Spring默认取决于是否抛出runtime异常).?
如果抛出runtime exception 并在你的业务方法中没有catch到的话,事务会回滚。?
一般不需要在业务方法中catch异常,如果非要catch,在做完你想做的工作后(比如关闭文件等)一定要抛出runtime exception,否则spring会将你的操作commit,这样就会产生脏数据.所以你的catch代码是画蛇添足。?
由此可以推知,在spring中如果某个业务方法被一个?
Java代码??
- try?{??
- ????//bisiness?logic?code??
- }?catch(Exception?e)?{??
- ????//handle?the?exception??
- }??
整个包裹起来,则这个业务方法也就等于脱离了spring事务的管理,因为没有任何异常会从业务方法中抛出!全被捕获并吞掉,导致spring异常抛出触发事务回滚策略失效。?
不过,如果在catch代码块中采用页面硬编码的方式使用spring api对事务做显式的回滚,这样写也未尝不可。?
2010-6-18日按:?
专业翻译人事给翻的?感谢哈:?
http://www.codeweblog.com/spring-trigger-transaction-rollback-exception-thrown-strategy/
?
?
源地址 ?http://wuaner.iteye.com/blog/583943
?
?
?