Transaction has been rolled back because it has been marked as rollback
来源:互联网 发布:北京网络电视台客户端 编辑:程序博客网 时间:2024/05/19 08:38
框架采用的是spring管理声明式事务,这几天业务开发时遇到了点麻烦,记录下备忘。
场景:在Service类中使用子事务(saveponit)时,当子事务抛出异常后,此异常处理掉不继续往外抛,spring在提交主事务时会抛出
org.springframework.transaction.UnexpectedRollbackException: Transaction has been rolled back because it has been marked as rollback
方法调用结构:
假若有A、B、C三个Service类,其实例对象分别为a、b、c,类分别定义如下:
A {
方法() { //propagation="REQUIRED"
try{
b.方法();
} catch (Exception e) {
}
}
}
B{
savePoint方法() { //propagation="NESTED"
c.方法(); //如果这里边的操作全是普通类(不是Service类)操作,不会有问题。
}
}
C{
方法() { //propagation="REQUIRED"
throw new Exception("出错");
}
}
通过调试spring源码
......
Getting transaction for [A.方法] .....
......
Creating nested transaction with name [B.savePoint方法]........
......
Participating in existing transaction
Getting transaction for [C.方法]
........
Participating transaction failed - marking existing transaction as rollback-only
//此时,已把主事务标记成了rollback-only
所以,当在a.方法完成时提交事务时会报Transaction has been rolled back because it has been marked as rollback错误。
认真的您可能会发现,在 org.springframework.transaction.support.AbstractPlatformTransactionManager 中有个叫
isGlobalRollbackOnParticipationFailure的参数,默认是true.
源码中说明:
Switch this to "false" to let the transaction originator make the rollback decision. If a participating transaction fails with an exception, the caller can still decide to continue with a different path within the transaction. However, note that this will only work as long as all participating resources are capable of continuing towards a transaction commit even after a data access failure: This is generally not the case for a Hibernate Session, for example; neither is it for a sequence of JDBC insert/update/delete operations.
大意是:如果isGlobalRollbackOnParticipationFailure为false,则会让主事务决定回滚,如果当遇到exception加入事务失败时,调用者能继续在事务内决定是回滚还是继续。然而,要注意是那样做仅仅适用于在数据访问失败的情况下且只要所有操作事务能提交。
初步解决方案:
<bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource" /><property name="globalRollbackOnParticipationFailure" value="false" /> <!--指定此参数为false-->
</bean>
经测试,此问题暂时得到解决,不知道会不会引起其它问题,至少目前还没有发现其它异常。您若通过此方案解决之后出现了新的问题请留信回复,我们一起交流,非常感谢!
- Transaction has been rolled back because it has been marked as rollback
- Transaction has been rolled back because it has been marked as rollback .
- Transaction rolled back because it has been marked as rollback-only
- spring事务 Transaction rolled back because it has been marked as rollback-only
- Transaction rolled back because it has been marked as rollback-only
- Transaction rolled back because it has been marked as rollback-only
- Transaction rolled back because it has been marked as rollback-only
- Transaction rolled back because it has been marked as rollback-only
- UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
- Transaction rolled back because it has been marked as rollback-only
- Transaction rolled back because it has been marked as rollback only
- Transaction rolled back because it has been marked as rollback-only”
- “Transaction rolled back because it has been marked as rollback-only”
- Srping Transaction rolled back because it has been marked as rollback-only解决方案
- Transaction rolled back because it has been marked as rollback-only
- Transaction rolled back because it has been marked as rollback-only
- “Transaction rolled back because it has been marked as rollback-only”
- Transaction rolled back because it has been marked as rollback-only”
- Android Camera Framework Stream(二)
- centos(6) ssh 自动登录配置
- Linux下的多线程编程
- 关键字new
- Android内存泄漏简介
- Transaction has been rolled back because it has been marked as rollback
- 线程!线程!!线程!!!(Delphi版)
- Linux 内核编译 添加系统调用
- SharePoint-WebPart中动态选择站点和列表
- Delphi开发的DICOM多窗浏览组件
- Windows外壳名字空间的浏览
- Android Camera Framework Stream(三)
- android内存泄露 mat
- sealed