spring事务传播之required nested requires_new

本文详细探讨了Spring事务传播中的required、nested和requires_new三种模式在异常情况下的表现。在不同场景下,它们对事务回滚的影响各异,特别是nested模式,它结合了required和requires_new的特点。当异常发生时,nested和requires_new能在try-catch处理后体现出事务的独立性。总结来说,nested在事务嵌套中扮演了复杂但关键的角色。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



一)A中异常情况


1)serverB.B  REQUIRED 的结果      全部回滚数据不变

2)serverB.B  NESTED    的结果      全部回滚数据不变

3)serverB.B  REQUIRES_NEW的结果    serverB.B 不回滚如图:

结论:

此种情况required 和nested 结果相同

REQUIRES_NEW作为一个新的事务时独立执行的

 

二) B中异常情况

 

1)serverB.B  REQUIRED 的结果      全部回滚数据不变

2)serverB.B  NESTED    的结果      全部回滚数据不变

3)serverB.B  REQUIRES_NEW的结果    全部回滚数据不变

结论:

顺序执行不做异常处理时:三者执行的结果一致

 

三)B中异常情况  server.B try_catch 处理

 

1)serverB.B  REQUIRED 的结果      全部回滚数据不变

2)serverB.B  NESTED    的结果      B回滚,A不会滚如图

3)serverB.B  REQUIRES_NEW的结果    B回滚,A不会滚如图

 

结论:

requires_new nested 是事务独立,但是异常报给A方法后导致了A回滚,只有try_catch处理后才能体现requires_new nested的事务独立性

 


最终的结论:

nested 作为事务嵌套,同时兼具了required,requires_new的特性。

当外层事务回滚时nested required 同时内层全部进行回滚

当内层事务回滚时,rested requires_new 不影响外层事务




另:nested 还有对版本的要求,还没有细看,看网上的各种文章也没有说明 需要try—catch处理,不知道是不是太显而易见,所以大家都没有说,如有错误欢迎指正。

 

### Spring事务传播行为的详细中文解释 以下是Spring事务传播行为的详细说明,涵盖每种传播行为的特点适用场景: #### 1. **REQUIRED** - 如果当前存在事务,则支持当前事务;如果没有事务,则创建一个新的事务。 - 这是默认的传播行为,适用于大多数需要事务支持的业务场景[^1]。 - 示例:核心业务逻辑通常使用`REQUIRED`。 ```java @Transactional(propagation = Propagation.REQUIRED) public void requiredMethod() { // 核心业务逻辑 } ``` #### 2. **SUPPORTS** - 如果当前存在事务,则支持当前事务;如果没有事务,则以非事务方式执行。 - 适用于那些可以运行在事务上下文中的方法,但本身不需要强制要求事务的存在[^3]。 - 示例:查询操作或读取数据的操作可以使用`SUPPORTS`。 ```java @Transactional(propagation = Propagation.SUPPORTS) public void supportsMethod() { // 查询操作 } ``` #### 3. **MANDATORY** - 如果当前存在事务,则支持当前事务;如果没有事务,则抛出异常。 - 适用于必须在事务上下文中运行的业务逻辑,如果未检测到现有事务则认为环境配置错误[^1]。 - 示例:关键业务逻辑可能需要确保始终运行在事务中,因此可以选择`MANDATORY`。 ```java @Transactional(propagation = Propagation.MANDATORY) public void mandatoryMethod() { // 关键业务逻辑 } ``` #### 4. **REQUIRES_NEW** - 创建一个新的事务,并将当前事务挂起。 - 即使当前存在事务,也会忽略它并创建一个全新的事务。 - 适用于需要独立提交或回滚的业务逻辑,与外部事务相互独立[^1]。 - 示例:日志记录或关键独立操作通常使用`REQUIRES_NEW`。 ```java @Transactional(propagation = Propagation.REQUIRES_NEW) public void requiresNewMethod() { // 独立操作 } ``` #### 5. **NOT_SUPPORTED** - 以非事务方式执行操作,并将当前事务挂起。 - 适用于不需要事务支持的操作,例如查询或只读操作。 - 使用`NOT_SUPPORTED`的好处是可以避免潜在的事务相关问题,如死锁或锁竞争[^3]。 ```java @Transactional(propagation = Propagation.NOT_SUPPORTED) public void notSupportedMethod() { // 只读操作 } ``` #### 6. **NEVER** - 以非事务方式执行,如果当前存在事务,则抛出异常。 - 适用于明确不需要事务支持的业务逻辑,任何事务上下文都被视为非法。 - 示例:某些只读查询操作可以使用`NEVER`[^3]。 ```java @Transactional(propagation = Propagation.NEVER) public void neverMethod() { // 明确不需要事务的逻辑 } ``` #### 7. **NESTED** - 如果当前存在事务,则在嵌套事务内执行;如果没有事务,则进行与`REQUIRED`类似的操作。 - 嵌套事务可以独立于外部事务提交或回滚,但仍然依赖于外部事务的存在。 - 示例:部分回滚需求或需要保存点的场景可以使用`NESTED`[^2]。 ```java @Transactional(propagation = Propagation.NESTED) public void nestedMethod() { // 需要保存点的逻辑 } ``` ### 注意事项 - 在选择事务传播行为时,需结合具体的业务场景进行决策。 - `NESTED`事务的实现依赖于数据库的支持,例如MySQL的保存点机制[^2]。 - `NOT_SUPPORTED``NEVER`适用于不需要事务支持的操作,但在处理异常时需特别小心[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值