现场情况是有两个 service:service1,service2;这两个里面都是用的编程式事务,如下。
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
//CODE
}
});
如果有异常是以 status.setRollbackOnly() ;
方式回滚; 现在有个 biz 层 bizA 调这两个 service
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
service1();
service2();
});
要保证这两个 service 同时成功,有一个回滚了那整体要回滚,因为不是用的注解式的事务,所以同样包了一层,事务嵌套事务 transactionTemplate.execute 结果执行的时候出现了文章开头的错误;最后查阅了资料后终于解决,记录如下: 原因:因为历史原因,service1 和 service2 是对外提供的接口;有错误是以错误码的形式返回的,所以 biz 层的事务和 service 层其实是同一个事务,在 service 层更改了 status,而 biz 层并不知道,还是继续 commit,就导致了 status 非 has been marked as rollback-only 异常。所以解决方案就是 biz 层在调用完 service 后一定要判断下是否成功,不成功的话要在 biz 层再做一遍 status.setRollbackOnly();
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于