当前位置: 首页 > news >正文

Spring--事务传播行为(REQUIRED / REQUIRES_NEW / NESTED)

🔵 1. REQUIRED(默认)

🧠 概念:

  • 当前存在事务 → 加入当前事务

  • 当前不存在事务 → 新建事务

  • 事务统一提交或回滚


📌 情况 1:外层无事务 → 启动新事务

➕ 子方法也使用 REQUIRED(新建事务)
// 外层无事务
public void outer() {inner();  // -> 新建事务
}@Transactional(propagation = Propagation.REQUIRED)
public void inner() {// 执行数据库写入// 抛出异常将回滚自己新建的事务
}

✅ inner() 自己新建事务 → 异常只影响自身,outer 不受影响。


📌 情况 2:外层有事务 → 子方法加入当前事务

➕ 子方法也使用 REQUIRED(共享事务)
@Transactional
public void outer() {inner();     // 加入同一个事务throw new RuntimeException();  // 异常导致整个事务回滚
}@Transactional(propagation = Propagation.REQUIRED)
public void inner() {// 写数据库
}

🟥 回滚行为:

  • outer中出现异常:outer 抛出异常 → outer + inner 全部回滚

  • inner中出现异常:inner 抛异常未捕获 → 整体回滚

  • inner中出现异常:inner 抛异常被 outer 捕获 → 也会整体回滚

    • 当 inner () 抛出 RuntimeException 时,Spring 会标记整个事务为 rollback-only,即使 outer () 捕获并处理了异常,在提交时也会强制回滚整个事务 T1。


🔴 总结:

外层是否有事务inner 事务是否共享事务回滚影响
❌ 无事务新建事务异常回滚自身
✅ 有事务加入事务谁异常谁负责,全局回滚


🟡 2. REQUIRES_NEW

🧠 概念:

  • 总是开启新事务

  • 如果外层已有事务 → 将其挂起

  • 子方法的事务与外层事务完全隔离


📌 情况 1:外层无事务 → 子方法新建事务

public void outer() {inner();  // 启动新事务
}@Transactional(propagation = Propagation.REQUIRES_NEW)
public void inner() {// 正常提交或回滚,与外层无关
}

✅ 单独事务,inner 的提交/回滚不影响 outer。


📌 情况 2:外层有事务 → 子方法新建新事务(挂起外层)

@Transactional
public void outer() {inner();  // 新事务,与 outer 不相关throw new RuntimeException();  // outer 回滚,但 inner 成功
}@Transactional(propagation = Propagation.REQUIRES_NEW)
public void inner() {// 新事务提交成功
}

🟢 回滚行为:

  • inner 正常 → 提交成功

  • outer 抛异常 → 仅回滚 outer,不影响 inner

  • 适合日志写入等场景


📌 情况 3:子事务异常,outer 捕获处理

@Transactional
public void outer() {try {inner();  // 抛异常被捕获} catch (Exception e) {System.out.println("记录失败,继续流程");}// outer 继续执行,最终提交
}@Transactional(propagation = Propagation.REQUIRES_NEW)
public void inner() {throw new RuntimeException("记录失败");
}

✅ inner 异常回滚,不影响 outer 提交。


🔴 总结:

外层是否有事务inner 事务是否共享事务回滚影响
❌ 无事务新建事务inner 控制自己回滚
✅ 有事务新建事务,挂起 outerinner 异常不影响 outer,反之也一样


🟢 3. NESTED

🧠 概念:

  • 有事务 → 创建嵌套事务(Savepoint)

  • 无事务 → 相当于 REQUIRED

  • 依赖父事务 → 嵌套事务提交前父事务回滚,嵌套也回滚

  • 嵌套事务回滚 → 父事务可选择是否继续(局部回滚)


📌 情况 1:外层无事务 → 和 REQUIRED 相同

public void outer() {inner();  // 启动新事务
}@Transactional(propagation = Propagation.NESTED)
public void inner() {// 单独控制事务(但其实是新建)
}

📌 情况 2:外层有事务,inner 嵌套事务中抛异常

@Transactional
public void outer() {try {inner(); // 抛异常} catch (Exception e) {System.out.println("inner failed, outer continues");}// outer 继续执行
}@Transactional(propagation = Propagation.NESTED)
public void inner() {throw new RuntimeException("inner error");
}

🟡 如果事务管理器支持 Savepoint(如 DataSourceTransactionManager):

  • inner 异常 → 回滚到 savepoint,outer 仍可继续提交

  • 实现部分回滚


📌 情况 3:外层事务最终抛异常

@Transactional
public void outer() {inner(); // 正常执行throw new RuntimeException("outer failed");
}@Transactional(propagation = Propagation.NESTED)
public void inner() {// 执行成功,但最终也回滚
}

🟥 注意:

  • inner 提交了?不!因为它只是父事务的 savepoint,父事务一旦回滚,嵌套事务也随之回滚


🔴 总结:

外层是否有事务inner 行为是否独立提交回滚行为
❌ 无事务新建事务(等价 REQUIRED)自己控制
✅ 有事务创建 savepoint❌ 依附外层事务inner 可部分回滚,但 outer 回滚则全回滚


✅ 三者对比总结表

传播行为外层有事务子事务是否新建是否和外层隔离外层异常是否影响子事务子事务异常是否影响外层事务
REQUIRED✅ 新建事务❌ 不隔离❌ 不影响(自身控制)❌ 不影响(自身控制)
REQUIRED❌ 加入外层事务❌ 不隔离✅ 影响✅ 影响
REQUIRES_NEW✅ 新建事务✅ 完全隔离❌ 不影响❌ 不影响(除非显式传播)
REQUIRES_NEW✅ 新建事务(挂起外层)✅ 完全隔离❌ 不影响❌ 不影响
NESTED✅ 新建事务❌ 不隔离❌ 不影响❌ 不影响
NESTED创建 savepoint❌ 局部隔离✅ 影响全部❌ 可被捕获实现局部回滚
http://www.lryc.cn/news/596840.html

相关文章:

  • 【图像处理基石】如何对遥感图像进行目标检测?
  • 【Linux | 网络】应用层(HTTPS)
  • 【数据结构初阶】--树和二叉树先导篇
  • 床上肢体康复机器人的机械结构设计cad【7张】三维图+设计说明书
  • #Linux内存管理# 在一个播放系统中同时打开几十个不同的高清视频文件,发现播放有些卡顿,打开视频文件是用mmap函数,请简单分析原因。
  • GEMINUS 和 Move to Understand a 3D Scene
  • 基于 XGBoost 与 SHAP 的医疗自动化办公与可视化系统(下)
  • 【计算机三级网络】——选择题高频考点(第一篇)
  • SQL基础⑧ | 表格篇
  • Python设计模式 - 桥接模式
  • 腾讯iOA:企业软件合规与安全的免费守护者
  • 炬森精密:缓冲滑轨的创新力量,重塑家居静音与安全新体验
  • LeetCode二叉树的公共祖先
  • 亚远景-传统功能安全VS AI安全:ISO 8800填补的标准空白与实施难点
  • 漏洞生命周期管理:从发现到防护的全流程方案
  • 基于Python(Django)+MongoDB实现的(Web)新闻采集和订阅系统
  • #C语言——学习攻略:操作符的探索(二)
  • ES6 标签模板:前端框架的灵活利器
  • mongodb的备份和还原(精简)
  • HarmonyOS Flutter Boost完全接入手册:爬完所有坑的实战指南
  • DeepSeek-R1大模型实战:AI编程助手如何提升开发效率
  • JVM、Dalvik、ART区别
  • 用Python实现卷积神经网络(一)
  • 电子电气架构 --- 汽车软件全生命周期
  • Java 堆(优先级队列)
  • 226.翻转二叉树
  • JAVA_EVLEN-面向对象高级二
  • 【C语言进阶】动态内存管理(2)
  • 新手向:Idea的使用技巧
  • 10. isaacsim4.2教程-RTX Lidar 传感器