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

Spring 事务传播机制:深入理解与实践

Spring 事务传播机制:深入理解与实践

在企业级开发中,事务管理是确保数据一致性和完整性的关键。在 Spring 中,事务通过 @Transactional 注解轻松实现,开发者可以控制事务的边界、传播行为以及回滚策略。在复杂的应用场景中,事务的传播机制决定了不同方法间事务的管理方式。Spring 提供了七种事务传播机制,它们定义了方法在被调用时是否创建新事务、加入现有事务或以其他方式执行。

本篇博客将带你深入理解每种传播机制,并讨论它们的内外部事务关系及是否会导致回滚的情况。让我们一起通过具体例子,逐步掌握如何在实际开发中合理使用这些传播机制。


1. Propagation.REQUIRED —— 坚持不懈,勇往直前

励志:无论何时何地,事务都要向前冲,加入现有的事务队伍,不留一丝犹豫。

  • 解释REQUIRED 是 Spring 的默认事务传播方式。如果当前已经存在一个事务,方法会加入该事务;如果当前没有事务,Spring 会创建一个新的事务。这种机制确保方法总是在事务中执行,无论外部是否已有事务。

  • 内部与外部事务的关系:内部事务始终加入外部事务中,共享同一个事务。如果外部事务回滚,内部事务也会回滚。

  • 回滚情况:一旦任何一个方法抛出未捕获的异常,整个事务(包括内外部事务)都会回滚。

示例代码

@Service
public class MyService {

    @Transactional(propagation = Propagation.REQUIRED)
    public void outerMethod() {
        // 外层事务开启
        innerMethod();  // 调用带有 REQUIRED 的方法
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void innerMethod() {
        // 内外事务共享同一事务
        // 如果 outerMethod 失败,innerMethod 也会回滚
    }
}

2. Propagation.REQUIRES_NEW —— 自我独立,勇敢前行

励志:无论前方多么复杂,我总是自立于外,创造属于自己的天地,独立完成任务。

  • 解释:每次调用方法时,都会开启一个新的事务。如果当前有事务,Spring 会挂起现有事务,并创建一个全新的事务。REQUIRES_NEW 是完全独立的,它不会依赖或影响外部事务。

  • 内部与外部事务的关系:内外事务完全独立。外部事务会在调用 REQUIRES_NEW 方法时被挂起,等内部事务结束后恢复。两者互不影响。

  • 回滚情况:如果外部事务回滚,内部的 REQUIRES_NEW 事务已经提交,不会受到影响;如果内部事务回滚,也不会影响外部事务。

示例代码

@Service
public class MyService {

    @Transactional(propagation = Propagation.REQUIRED)
    public void outerMethod() {
        // 外层事务开启
        try {
            innerMethod();  // 调用带有 REQUIRES_NEW 的方法
        } catch (Exception e) {
            // 捕获异常,外层事务不回滚
        }
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void innerMethod() {
        // 开启新事务,外层事务将被挂起
        // 抛出异常会导致 innerMethod 的事务回滚,但不会影响 outerMethod
        throw new RuntimeException("Inner method failed");
    }
}

3. Propagation.SUPPORTS —— 随机应变,适应环境

励志:无论环境如何,我都能灵活适应,跟随事务,或者独自行动。

  • 解释:如果当前有事务,方法会加入该事务;如果当前没有事务,方法则以非事务方式执行。这种传播机制通常用于那些对事务要求不高的操作。

  • 内部与外部事务的关系:如果外部有事务,内部会加入;如果外部没有事务,内部方法将独立执行,不创建事务。

  • 回滚情况:如果加入外部事务,则根据外部事务的回滚规则;如果外部没有事务,则无事务处理,方法抛出异常不会有事务回滚。

示例代码

@Service
public class MyService {

    @Transactional(propagation = Propagation.REQUIRED)
    public void outerMethod() {
        // 外层事务开启
        innerMethod();  // 调用带有 SUPPORTS 的方法
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    public void innerMethod() {
        // 如果 outerMethod 有事务,innerMethod 加入该事务
        // 如果 outerMethod 没有事务,innerMethod 以非事务方式执行
    }
}

4. Propagation.NOT_SUPPORTED —— 摆脱束缚,独立前行

励志:我拒绝参与事务的争斗,跳出事务的框架,自由自在。

  • 解释:不支持事务。如果当前有事务,Spring 会挂起该事务,并以非事务方式执行方法。适用于那些不需要事务支持的操作。

  • 内部与外部事务的关系:外部事务在执行此方法时被挂起,内部以非事务方式独立运行。

  • 回滚情况:方法以非事务方式运行,不会有回滚。

示例代码

@Service
public class MyService {

    @Transactional(propagation = Propagation.REQUIRED)
    public void outerMethod() {
        // 外层事务开启
        innerMethod();  // 调用带有 NOT_SUPPORTED 的方法
    }

    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void innerMethod() {
        // 外层事务会被挂起,innerMethod 以非事务方式执行
        // 无论发生什么,innerMethod 不会影响 outerMethod 的事务
    }
}

5. Propagation.MANDATORY —— 信任团队,共同作战

励志:我不能单打独斗,我必须依靠现有的事务战斗,才能赢得胜利。

  • 解释:方法必须在一个现有事务中执行。如果当前没有事务,Spring 会抛出异常。适用于那些必须依赖外部事务的操作。

  • 内部与外部事务的关系:必须有外部事务,内部事务加入外部事务。

  • 回滚情况:回滚规则与外部事务一致,外部回滚会导致内部回滚。

示例代码

@Service
public class MyService {

    public void outerMethod() {
        innerMethod();  // 调用带有 MANDATORY 的方法
    }

    @Transactional(propagation = Propagation.MANDATORY)
    public void innerMethod() {
        // 必须在已有事务中执行,没有事务则抛出异常
    }
}

6. Propagation.NEVER —— 坚决独立,拒绝依赖

励志:我绝不加入任何事务,事务对我来说是阻碍,独立完成才是我的风格。

  • 解释:方法不允许在事务中执行。如果当前有事务,Spring 会抛出异常。适用于那些绝对不需要事务支持的操作。

  • 内部与外部事务的关系:如果外部事务存在,方法将抛出异常。

  • 回滚情况:没有事务,抛出异常不会有事务回滚。

示例代码

@Service
public class MyService {

    @Transactional(propagation = Propagation.REQUIRED)
    public void outerMethod() {
        innerMethod();  // 调用带有 NEVER 的方法
    }

    @Transactional(propagation = Propagation.NEVER)
    public void innerMethod() {
        // 如果有事务,则抛出异常
    }
}

7. Propagation.NESTED —— 协同作战,独立进退

励志:我们虽共同前行,但我有独立的判断,随时准备在关键时刻独自决策。

  • 解释:如果当前有事务,则开启一个嵌套事务;如果当前没有事务,表现为 REQUIRED。嵌套事务有自己的回滚点,可以独立回滚,但如果外部事务回滚,嵌套事务也会回滚。

  • 内部与外部事务的关系:内部事务是外部事务的嵌套部分,外部事务回滚时,内部嵌套事务也会回滚。内部事务可以单独回滚,而不影响外部事务。

  • 回滚情况:内部事务可以独立回滚,外部事务回滚时,嵌套事务也会回滚。

示例代码

@Service
public class MyService {

   

 @Transactional(propagation = Propagation.REQUIRED)
    public void outerMethod() {
        innerMethod();  // 调用带有 NESTED 的方法
    }

    @Transactional(propagation = Propagation.NESTED)
    public void innerMethod() {
        // 开启嵌套事务
        // 如果 outerMethod 回滚,innerMethod 也会回滚
        // 如果 innerMethod 回滚,不影响 outerMethod
    }
}

总结

Spring 提供的七种事务传播机制,帮助我们在复杂业务场景中灵活控制事务的行为。通过合理选择传播机制,我们可以确保数据库操作的原子性和数据的一致性。无论是 REQUIRED 的无条件加入,还是 REQUIRES_NEW 的独立事务,亦或是 NESTED 的灵活嵌套,理解这些机制将极大提升你在实际开发中的事务管理能力。

每一种传播机制都有自己的独特用例和适用场景,了解它们的内外事务关系以及回滚规则,是我们掌控事务边界、提高代码健壮性的关键。


http://www.kler.cn/news/340635.html

相关文章:

  • 20241005给荣品RD-RK3588-AHD开发板刷Rockchip原厂的Android12时使用iperf3测网速
  • 某象异形滑块99%准确率方案
  • Springboot 整合 logback 日志框架
  • 校园资源共享新方案:基于SpringBoot的实现
  • 基于SpringBoot+Vue的在线投票系统
  • 【Unity】unity安卓打包参数(个人复习向/有不足之处欢迎指出/侵删)
  • Matter蓝牙解析
  • 06-Cesium 中动态处理与圆形扩散材质相关的属性
  • [nmap] 端口扫描工具的下载及详细安装使用过程(附有下载文件)
  • Java 中的 PO、VO、DAO、BO、DTO、POJO
  • 文件分块上传
  • 黑神话:仙童,数据库自动反射魔法棒
  • 【自动驾驶汽车通讯协议】I2C(IIC)总线通讯技术详解
  • Windows环境安装CentOS7
  • Lumerical 脚本语言——操作实体对象(Manipulating objects)
  • unix进程间通信信号的有效实践
  • 用KLineChart绘制股票行情K线图
  • 163页PPT罗兰贝格品牌战略升级:华为案例启示与电器集团转型之路
  • 《PyTorch深度学习快速入门教程》学习笔记(第15周)
  • 国产长芯微LUM6100高可靠性双通道双向I2C数字隔离器P2P替代ADUM1250 ADUM1251替代ISO1540 ISO1541