spring的事务中程序控制事务成功失败(Transaction marked as rollback)

本文讨论了在Spring框架下使用事务管理时遇到异常导致事务被标记为回滚的情况,以及通过调整配置参数来解决该问题的方法。具体而言,文章解释了`globalRollbackOnParticipationFailure`参数的作用,即在参与事务失败时是否触发全局回滚,并提供了如何修改该参数以适应特定业务需求的指导。
A方法之外加有事务管理拦截器,在A方法中做一系列操作,操作过程中捕获了一个异常,因为此异常不影响业务,捕获后需要正常向下运行,最终事务管理器提交事务时报了如下错误
Transaction has been rolled back because it has been marked as rollback 
原因就是发生异常后当前的事务就被标记为rollback-only,外层事务管理器再commit时就会抛此异常,解决方法是
<bean id="transactionManager"
  class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  <property name="sessionFactory">
   <ref bean="sessionFactory" />
  </property>
  <property name="globalRollbackOnParticipationFailure" value="false" />
 </bean>

在 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加入事务失败时,调用者能继续在事务内决定是回滚还是继续。然而,要注意是那样做仅仅适用于在数据访问失败的情况下且只要所有操作事务能提交。

### 关于事务被标记为 rollback-only 的原因 当一个事务被标记为 `rollback-only`,通常意味着该事务已经无法提交成功,并且唯一的选择是回滚。这种状态可能由多种因素引起: #### 原因分析 1. **程序逻辑中的显式设置** 如果开发者在代码中调用了 `TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()` 方法,则会手动将当前事务标记为只允许回滚的状态[^1]。 2. **异常触发的自动回滚机制** 在声明式事务管理中,可以通过配置指定某些特定类型的异常(如运行时异常或自定义业务异常)来触发事务的自动回滚。如果这些异常发生而未被捕获并处理,则事务会被标记为 `rollback-only`[^2]。 3. **数据库层面的因素** 数据库内部的操作也可能导致事务进入不可恢复的状态。例如,在 Oracle 中,频繁的数据修改操作可能导致 `ORA-01555` 错误,这是因为快照数据丢失引起的。这种情况可能会间接影响到应用程序层面上的事务状态[^3]。 4. **资源不足或其他环境问题** 当系统缺乏足够的内存、磁盘空间或者网络连接中断等情况发生时,也有可能使得正在进行中的事务被迫终止并置为仅能回滚模式。 #### 解决方案探讨 针对以上提到的各种可能性,可以采取相应的措施来进行预防和修复: ##### 编程方面调整 - 避免不必要的强制性标志位设定:除非绝对必要,否则应减少直接通过API方法去改变事务属性的行为。 - 合理规划错误捕获流程:确保所有预期之外的情况都能得到妥善处置而不至于让整个过程崩溃掉;同时也要注意区分哪些情况确实应该引发整体失败从而执行rollbacks. ##### 配置优化建议 - 利用Spring框架提供的功能来自定义适合项目需求的一套规则体系,比如明确指出哪几类Exception应当关联至automatic rollbacks之上. - 考虑增加额外数量的undo tablespaces以满足并发量增高的场景下对于历史版本记录保存期限的要求.[^4] ##### 性能改进策略 - 对于大型查询语句尽量缩短其持续时间,防止因为长时间占用而导致其他依赖于此结果集的任务受到影响; - 定期维护数据库结构,包括但不限于扩展现有rollback segment大小或是创建新的实例用于分担压力负荷。 ```sql -- Example SQL command to alter undo tablespace status ALTER UNDO TABLESPACE innodb_undo_001 SET INACTIVE; ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值