原文:http://heroliuxun.iteye.com/blog/848122 java
今天遇到了一个这个问题spring
最近遇到这样的问题,使用spring时,在业务层须要捕获异常(特殊须要),当前通常状况下不须要这样作的。具体以下: 在ServiceA类中有method1,在该方法中调用另外一个ServiceB类的method2方法时(假定该方法抛出异常),method1方法捕获该异常可是没有向上抛出。spring提示:org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-onlyui
缘由是 先插入数据,而后调用另一个service 加入事务 另一个事务报错了,会抛这个异常 Transaction rolled back because it has been marked as rollback-onlyspa
相似于你再get方法里面操做数据(非只读)的错code
业务场景: 在一个service里面先操做(增删改)数据以后,而后调用另一个service(另一个业务),而另一个service抛异常,在你try catch这个业务的时候,spring默认会报 Transaction rolled back because it has been marked as rollback-only对象
@Transactional(rollbackFor = Throwable.class)//默认事务传播方式required public Class ServiceA { @Autowired private Dao dao; @Autowired private ServiceB serviceB; // 注入另外一Service Bean public void method1() { dao.insert(vo); // 保存ServiceA的vo对象 try { serviceB.method2(vo); // 保存ServiceB的vo对象 } catch (CustomException e) { // 捕获自定义异常,可是没有向上抛出 } } } 如下是ServiceB的示例代码 @Transactional(rollbackFor = Throwable.class)//默认事务传播方式required public Class ServiceB { @Autowired private Dao dao; public void method2() throws CustomException { dao.insert(vo); // 保存ServiceA的vo对象 } }
出现以上缘由是spring执行method1方法时,开启一个新的事物,当调用method2方法时,当method2方法加入到method1方法的当前事务,当method2抛出异常,spring标记事务为回滚状态,method1方法捕获该异常,但没有抛出,spring会提交method1的事务,但spring发现该事务已经标记为回滚状态,而代码中却要提交事务,因此才会抛出以上的异常。 解决的方法:在ServiceB的method2方法上注解,告诉spring当该方法抛出自定义异常CustomException时,不要回滚事务,这样当该方法抛出异常时,spring不会标记事务为回滚状态。 blog
@Transactional(noRollbackFor=CustomException.class) public void method2() throws CustomException{ }
感谢原文的博客事务