在写事务的时候经常会用到隐式事务@Transactional。具体事务内的propagation为默认的Propagation.REQUIRED。报错异常为:
造成该异常的方式网上说的很多。。我这里只给个例子:
有这么三个方法 service0.test、service.testA、service.testB(注:spring的事务生效是通过AOP动态代理切面生成的。故这里这三个方法的调用必需要通过方法调用,不可内部直接调用)
具体实现如下:
//类A的调用方法 @Transactional public String test(String value){ service.testA(value); try { service.testB(value); } catch (Exception e) { logger.info("输出个日志"); } return "成功"; } //====类B的两个方法 @Transactional @Override public void testA(String value) { Task task = dao.findByPrimaryKey(1L); task.value(value); task.updateByPrimaryKey(task); } @Transactional @Override public void testB(String value) { throw new RuntimeException("报个错, value:"+value); }
好了,运行以上代码就会报上面的异常。
那么大致是一个线性运行流程:
问题就出现在testB上的回滚流程,那么我们翻一下spring源码:
这里其实就是设定个标志位。。说回滚了。但并没有真实的回滚
但由于test方法去catch住了。。那么最外面的事务以为没有异常,那么它会走提交流程。。提交的时候发现rollbackOnly标志位为true..故就会看到你所见到的异常