Spring事务传播错误

开发中突然出现错误:

org.springframework.transaction.IllegalTransactionStateException: Transaction is already completed - do not call commit or rollback more than once per transaction
at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:829)
at com.longfor.longjian.evaluation.app.service.impl.QualityAppealServiceImpl.xTaskApprovalSubmitSubmit(QualityAppealServiceImpl.java:505)
at com.longfor.longjian.evaluation.app.service.impl.QualityAppealServiceImpl

实在莫名其妙,初步分析是由于事物完成之后又进行了commit,rollback操作。通过查看代码方法嵌套调用,而两个方法都有事物。
例如:方法A调用B方法,A和B中都有事物,这就应用到了spring事物传播。

问题原因

找到事物传播几种类型,发现spring默认将嵌套事物进行合并,通过断点观察我的B方法进行了rollback操作,而A方法进行了commit操作,rollback使本事物已经完成,不能进行commit操作。这就导致了上面的问题。

解决方法

解决方法需要将两个事物进行分开,不合并。可以使用PROPAGATION_REQUIRES_NEW或PROPAGATION_NESTED,
PROPAGATION_REQUIRES_NEW
1.运行到子事物是重新创建一个事物
2.子事物是否回滚不影响父级事物
3.父级事物是否回滚不影响子事物
PROPAGATION_NESTED(黄色为区别)
1.运行到子事物是重新创建一个事物
2.子事物是否回滚不影响父级事物
3.父级事物回滚子事物也回滚

代码

// A code block
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED);
TransactionStatus status = txManager.getTransaction(definition);

当然spring还有其他几种传播模式,我的业务中使用的是PROPAGATION_NESTED这种,其他几种可以参考链接: Spring事务传播模式.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当涉及到Spring事务的面试问题时,以下是一些常见的问题和参考答案: 1. 什么是Spring事务管理? Spring事务管理是一种将事务逻辑与业务逻辑分离的方式。它提供了一种简单的方法来管理数据库事务,并确保在发生错误或异常的情况下进行回滚或提交。 2. Spring事务管理的主要特性是什么? 主要特性包括: - 声明式事务管理:使用注解或XML配置来声明事务 - 编程式事务管理:在代码中使用编程方式控制事务 - 隔离级别:定义事务之间的隔离级别,如读未提交,读已提交,可重复读和串行化 - 传播行为:定义事务方法之间的调用关系,如PROPAGATION_REQUIRED和PROPAGATION_REQUIRES_NEW - 回滚规则:定义哪些异常会导致事务回滚 3. Spring事务管理有哪些常见的实现方式? 常见的实现方式包括: - 基于注解的事务管理:使用@Transactional注解来标记需要进行事务管理的方法 - 基于XML配置的事务管理:通过配置<tx:advice>和<tx:attributes>元素来进行事务管理 4. 什么是事务传播行为?Spring提供了哪些事务传播行为? 事务传播行为定义了事务方法之间的调用关系。Spring提供了多种事务传播行为,包括: - REQUIRED:如果当前存在事务,则加入该事务,否则新建一个事务。 - REQUIRES_NEW:无论当前是否存在事务,都创建一个新的事务,如果当前存在事务,则挂起当前事务。 - SUPPORTS:如果当前存在事务,则加入该事务,否则以非事务方式执行。 - NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,则挂起当前事务。 - MANDATORY:如果当前存在事务,则加入该事务,否则抛出异常。 - NEVER:以非事务方式执行操作,如果当前存在事务,则抛出异常。 5. Spring如何处理事务的并发问题? Spring使用数据库的事务隔离级别来处理并发问题。常见的隔离级别包括: - READ_UNCOMMITTED:允许读取未提交的数据,可能导致脏读、不可重复读和幻读问题。 - READ_COMMITTED:只能读取已提交的数据,可以避免脏读问题,但仍可能出现不可重复读和幻读问题。 - REPEATABLE_READ:保证同一事务内多次读取的数据是一致的,可以避免脏读和不可重复读问题,但仍可能出现幻读问题。 - SERIALIZABLE:最高级别的隔离级别,保证所有并发事务按照顺序依次执行,可以避免脏读、不可重复读和幻读问题,但性能较差。 这些是一些常见的Spring事务管理的面试问题和参考答案。当然,在面试过程中还可能有其他相关的问题,因此建议对Spring事务管理的原理和用法进行深入了解,准备充分以回答更多的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值