在使用spring事务管理时,程序报如下:
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
程序的代码为:
serviceA.methiodA{
beforedone;
methodB();
try{
serviceB.methodB{}; //这里面有异常标记为回滚, doSetRollbackOnly(status);
}catch{
//捕获异常转到commit时,由于已经标记为要回滚, 回滚并抛出新异常
}
other done;
}
//传播:propagation 为 Required
原来是自己没有弄懂spring事务的机制。
这个方法被调用执行时,有两个点是被spring事务代理。serviceA.methodA(),serviceB.methodB(),这两个方法中只要有异常事件将回滚。
(其实因为事务嵌套,serviceA#methodA中有异常标记并直接回滚,serviceB#methodB中有异常只是标记回滚状态,在调用回serviceA#methodA中回滚)。 这个方法中serviceB#methodB有异常事务被标记为回滚,继续执行到serviceA.methodA(), 可是被methodA捕获了,也就不回滚了,一直执行到最后commit。在commit时spring会判断回滚标志,若有回滚标记,回滚并抛出UnexpectedRollbackException异常。
如何解决:
上面就是serviceA#methodA中的方法不被serviceB#methodB影响。想到两个方法好像都不是很好。
1. serviceB.methodB不声明为事务代理。
很多时候serviceB.methodB也被其他地方,是要事务管理的。这时候可以重写一个方法。
但是要注意这个方法中数据的一致性。
2. 和1一样也是重写一个serviceB.methodBNE,里面不抛出异常,也要注意这个方法中数据的一致性。感觉是一样的。
个人感觉在使用尽量不捕获异常,以保证事务一致性,如果有如上面的需求
(如给所有人奖励物品时,当中可能有人条件不足而抛出异常,为不影响下面的要捕获)
可以独立一个包出来专门做一个对多人操作的。而不是在同一个service写两个一样的方法,
导致混乱。
不捕获则在调用serviceB.methodB()时就回滚不会到commit那。
从这次错误中可以得到:
1.弄清楚被spring事务代理方法有哪些,这些方法有异常事务都将回滚
(不含this.methodB调用,动态代理导致)
2. 被代理的方法内部有异常抛出,事务都会标记为回滚,并在最外层调用那回滚。
嵌套事务若是REQUIRED_NEW新事务则在那个方法调用时直接回滚
如上面serviceA#methodA中直接回滚, serviceB#methodB则只标记
3.在事务提交serviceA.methodA(最外层)中
commit(TransactionStatus)在具体提交事务之前会检查rollBackOnly状态,
如果该状态在methodB中被设置,那么转而执行事务的回滚操作。
rollBackOnly状态没被设置,则执行正常的事务提交操作。
分享到:
相关推荐
Spring事务管理Demo
Spring事务管理教程,详细讲解了Spring中的事务管理,包括声明式事务,注解式事务,以及事务配置等等
Spring事务管理.pdf 1.资料 2.本地事务与分布式事务 3.编程式模型 4.宣告式模型
spring 事务管理的理解
Synchronized锁在Spring事务管理下,导致线程不安全。
Spring事务管理(全),需要的可下载!
spring事务管理几种方式代码实例:涉及编程式事务,声明式事务之拦截器代理方式、AOP切面通知方式、AspectJ注解方式,通过不同方式实例代码展现,总结spring事务管理的一般规律,从宏观上加深理解spring事务管理特性...
spring事务管理 配置文件等详解
本代码使用H2内存数据库演示spring事务使用,包括编程式事务,声明式事务@Transactional使用,自定义事务事务注解实现自定义事务管理器
Java高级编程 实验报告 spring 声明事务 实验目的 掌握spring 声明式事务管理配置 实验环境 本实验采用本实验采用的eclipse或者 Myeclpse开发工具。Spring 4.0以上 Jdk1.7以上、oracle/mysql。
Spring事务管理中所需要的jar包是 spring-tx-3.2.0.RELEASE.jar
在该JAR包的org.springframework.transaction包中,有3个接口文件PlatformTransactionManager、TransactionDefinition和TransactionStatus,如下图所示: Spring事务管理的三个核心接口 5.1.1 事务管理的核心接口 1....
javaEE 实验三 Spring JDBC与事务管理, 一、实验目的 1、掌握Spring JDBC的配置; 2、掌握JdbcTemplae类中增删改查方法的使用; 3、了解Spring事务管理的3个核心接口; 4、了解Spring事务管理的两种方式; 5、掌握...
spring事务与数据库操作
Spring事务管理4种方式 入门级 最简单demo PlatformTransactionManager TransactionTemplate
Spring事务流程图时序图Spring事务流程图时序图Spring事务流程图时序图Spring事务流程图时序图
Spring声明式事务管理失效的原因,这里面是日常工作中踩过的坑,事务失效所产生的影响比较隐蔽,测试时易忽略,大多是在线上暴露,这可能是对Spring管理下的信任吧
Spring事务管理A方法内部调用B方法的回滚问题测试代码
此包含有所有Spring事务管理开发所需要的Jar包,包含框架、核心、表达式、日志、编译、事务切面aop、数据库连接、单元测试、框架文本等jar包。