Java 中事务传播行为 PROPAGATION_NESTED 怎么实现

陌杰小哥_6245

陌杰小哥_6245

2026-10-23

872人浏览

原创

propagation_nested 是基于 jdbc 保存点的伪嵌套事务,依赖 datasourcetransactionmanager 和支持 savepoint 的数据库,在同一物理事务中设置保存点实现局部回滚,非真正嵌套事务。

java 中事务传播行为 propagation_nested 怎么实现

PROPAGATION_NESTED 在 Spring 中并不是真正意义上的“嵌套事务”,而是基于 JDBC 保存点(Savepoint)实现的伪嵌套行为,仅在使用 JDBC 或支持 Savepoint 的数据源(如 MySQL、PostgreSQL)且事务管理器为 DataSourceTransactionManager 时才有效。

依赖底层数据库的 Savepoint 支持

它不依赖数据库本身的嵌套事务能力(多数关系型数据库并不原生支持真正的嵌套事务),而是在当前事务中设置一个保存点。如果内层逻辑回滚,只回滚到该保存点,外层事务仍可继续提交或回滚。

  • 必须使用支持 Savepoint 的 JDBC 驱动(主流数据库基本都支持)
  • 事务管理器不能是 JTA(如 JtaTransactionManager),因为 JTA 不支持 Savepoint
  • 不能与 PROPAGATION_REQUIRED 或其他传播行为混用后期望“独立事务上下文”——它始终运行在同一个物理事务中

典型使用方式和效果

当外层方法 A 调用内层方法 B,且 B 标注 @Transactional(propagation = Propagation.NESTED):

  • A 开启事务 → 获取 Connection → 设置 Savepoint S1
  • B 执行 → 若抛出未被捕获的 RuntimeException,触发回滚到 S1,但 A 的事务不受影响
  • A 可继续执行后续逻辑,最终决定 commit 或 rollback 整个事务

注意:B 中主动调用 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly() 或抛出异常,才会触发 Savepoint 回滚;若 B 内部自行捕获异常且不传播,A 完全感知不到。

代码示例(关键点标注)

⚠️ 前提:配置了 DataSourceTransactionManager,数据源开启 auto-commit=false,且数据库支持 Savepoint

@Service
public class OrderService {
    @Transactional
    public void createOrder(Order order) {
        // 外层事务:插入订单主表
        orderMapper.insert(order);

        try {
            processPayment(order); // 可能失败,但不影响订单插入
        } catch (Exception e) {
            log.warn("支付处理失败,已回滚至保存点", e);
        }

        // 即使 payment 失败,order 仍可提交
        notifySuccess(order);
    }

    @Transactional(propagation = Propagation.NESTED)
    public void processPayment(Order order) {
        // 内层:扣款、生成流水等操作
        paymentMapper.deduct(order.getUserId(), order.getAmount());
        transactionMapper.insert(new Transaction(...));
        // 若此处抛异常,仅回滚这两步,order 插入不受影响
    }
}

常见误区与限制

  • 不是新事务:没有新的 TransactionStatus,isNewTransaction() 返回 false
  • 无法跨线程生效:Savepoint 绑定在当前 JDBC Connection 和线程上,异步调用会丢失上下文
  • 不适用于 JPA/Hibernate 的 EntityManager:除非明确使用 JpaTransactionManager 并配置 jdbcExceptionTranslator,否则可能降级为 REQUIRED
  • 多个 NESTED 方法嵌套时,每个都会新建 Savepoint,回滚只作用于最近一级

Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

java

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

11037

6

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

2023.07.05

8142

9

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

2023.07.31

7052

8

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.01

1184

3

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.02

968

3

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

1436

5

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2909

5

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

2023.08.03

20191

3

配置java环境变量
配置java环境变量

配置Java环境变量是为了让操作系统能够识别和使用Java的相关命令和功能。本专题为大家提供配置java环境变量相关文章,帮助大家解决问题。

2023.08.03

1275

8

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习