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

Spring Boot 事务详解:原理与实操指南

在企业级应用开发中,数据一致性是核心需求之一。例如,电商系统中的下单操作需要同时扣减库存、创建订单记录,若中间某一步失败,必须保证所有操作回滚,避免数据错乱。Spring Boot 的事务管理机制正是解决这类问题的关键技术,它能通过简单配置实现复杂的事务控制。

一、事务的核心概念与 ACID 特性

事务(Transaction)是由一系列操作组成的不可分割的执行单元,要么全部成功,要么全部失败。一个可靠的事务必须满足 ACID 特性:

  • 原子性(Atomicity):事务中的所有操作要么全部完成,要么全部不完成,不存在部分成功的情况。例如,转账时 “扣款” 和 “收款” 必须同时成功或同时失败。
  • 一致性(Consistency):事务执行前后,数据从一个合法状态转换为另一个合法状态。例如,转账前后两个账户的总金额保持不变。
  • 隔离性(Isolation):多个并发事务之间相互隔离,一个事务的执行不应影响其他事务。隔离级别决定了并发事务之间的可见性(后文详细说明)。
  • 持久性(Durability):事务一旦提交,其结果将永久保存在数据库中,即使系统崩溃也不会丢失。

二、Spring Boot 事务的实现原理

Spring Boot 事务管理依托于 Spring Framework 的事务抽象机制,核心是声明式事务,通过@Transactional注解结合 AOP(面向切面编程)实现对业务方法的事务控制。这种方式无需手动编写事务的开启、提交和回滚代码,而是由框架自动完成,极大简化了开发。以下从核心组件、执行流程、传播行为、隔离级别及源码层面详细解析。

1. 核心组件与接口

Spring 事务管理的核心由三个关键接口构成,它们共同支撑起事务的创建、执行和状态管理:

(1)PlatformTransactionManager:事务管理器

PlatformTransactionManager是事务管理的核心接口,定义了事务操作的基本规范,包括创建事务、提交事务和回滚事务,其源码如下:

public interface PlatformTransactionManager {// 根据事务定义创建事务TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException;// 提交事务void commit(TransactionStatus status) throws TransactionException;// 回滚事务void rollback(TransactionStatus status) throws TransactionException;
}

主要实现类

  • DataSourceTransactionManager:适用于 JDBC、MyBatis 等基于DataSource的数据源,通过操作数据库连接(Connection)来控制事务。
  • JpaTransactionManager:针对 JPA 技术,整合 JPA 的EntityManager进行事务管理。
  • HibernateTransactionManager:专门用于 Hibernate 框架的事务管理。

以DataSourceTransactionManager为例,其getTransaction方法会从数据源获取连接,并根据事务定义设置连接的事务属性,核心逻辑如下:

@Override
public TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException {// 获取数据库连接(从ThreadLocal中获取已绑定的连接或新建连接)ConnectionHolder conHolder = TransactionSynchronizationManager.getResource(this.dataSource);// 根据事务定义(传播行为、隔离级别等)处理事务if (conHolder != null && !conHolder.isSynchronizedWithTransaction()) {// 若已有连接但未关联事务,依据传播行为进行处理(如REQUIRED则加入事务)...}// 配置连接的事务属性(如设置autoCommit为false)Connection con = conHolder.getConnection();Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);// 返回事务状态对象return new DefaultTransactionStatus(...);
}

(2)TransactionDefinition:事务定义

TransactionDefinition定义了事务的各种属性,包括传播行为、隔离级别、超时时间等,源码如下:

public interface TransactionDefinition {// 传播行为int getPropagationBehavior();// 隔离级别int getIsolationLevel();// 超时时间(秒)int getTimeout();// 是否为只读事务boolean isReadOnly();// 事务名称@NullableString getName();
}

默认实现类:DefaultTransactionDefinition,提供了默认的属性值,如传播行为默认REQUIRED,隔离级别默认DEFAULT。

(3)TransactionStatus:事务状态

TransactionStatus表示当前事务的运行状态,如是否活跃、是否已回滚等,源码如下:

public interface TransactionStatus extends SavepointManager, Flushable {// 是否为新事务boolean isNewTransaction();// 是否有保存点boolean hasSavepoint();// 设置事务为回滚状态void setRollbackOnly();// 是否需要回滚boolean isRollbackOnly();// 刷新事务@Overridevoid flush();// 事务是否已完成boolean isCompleted();
}

DefaultTransactionStatus是其实现类,记录了事务的核心状态,是事务管理器判断事务提交或回滚的重要依据。

2. 事务的传播行为

事务的传播行为定义了当一个事务方法调用另一个事务方法时,新事务的创建规则。Spring 定义了 7 种传播行为,具体如下:

  • REQUIRED(默认):如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新事务。
    • 示例:ServiceA 的 methodA(带事务)调用 ServiceB 的 methodB(传播行为为 REQUIRED),methodB 会加入 methodA 的事务,若 methodB 执行失败,methodA 的操作也会回滚。
  • REQUIRES_NEW:无论当前是否存在事务,都创建一个新事务,原事务暂停。
    • 示例:订单创建方法(带事务)调用日志记录方法(传播行为为 REQUIRES_NEW),即使订单创建失败回滚,日志记录也会成功提交。
  • SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务方式执行。
    • 示例:查询操作方法,若被事务方法调用则在事务中执行,若单独调用则无事务。
  • NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,则暂停该事务。
    • 示例:耗时的统计分析操作,不需要事务支持,若在事务中调用会暂停原事务。
  • NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
    • 示例:明确不允许在事务中执行的操作,若被事务方法调用则报错。
  • MANDATORY:必须在一个已存在的事务中执行,若当前没有事务,则抛出异常。
    • 示例:某些关键的更新操作,必须依赖于上层事务的存在。
  • NESTED:如果当前存在事务,则创建一个嵌套事务(嵌套在当前事务中);如果当前没有事务,则等同于 REQUIRED。
    • 示例:主事务执行核心操作,嵌套事务执行附加操作,嵌套事务失败可独立回滚,不影响主事务。

http://www.dtcms.com/a/324943.html

相关文章:

  • AQS(AbstractQueuedSynchronizer)底层源码实现与设计思想
  • 第三章-提示词:从0到1,提示词实训全攻略,解锁大语言模型无限潜能(14/36)
  • MyBatis Mapper核心组件协作关系深度解析
  • Java条件判断与用户交互实战案例
  • 【经典算法】二叉树最小深度详解:递归解法与可视化分析
  • 深入解析C#并行编程:从并行循环到异步编程模式
  • PyCATIA深度解析:基于装配截面自动化创建参考几何平面群的专业方案
  • 锂电生产设备健康管理:基于预测性维护的智能化解决方案​
  • 【github.io静态网页 怎么使用 github.io 搭建一个简单的网页?】
  • Python与MySQL数据库交互实践:自动化数据插入系统
  • GPU版的Pytorch安装(Win11)
  • SpringBoot项目自定义静态资源映射规则
  • 【嵌入式】Linux的常用操作命令 (1)
  • SAP 121移动类型的说明
  • C野指针的概念与应对(源头、阻隔、定位)
  • STM32定时器与延时系统完整笔记
  • 【C#补全计划】万类之父中的方法
  • 使用单调栈解决力扣第42题--接雨水
  • 亚麻云之静态资源管家——S3存储服务实战
  • SSH远程连接TRAE时显示权限被拒绝检查方案
  • 游泳学习 — 蛙泳
  • 变量详解:创建初始化与内存管理
  • go加速配置(下载第三方库)
  • go语言运算符
  • Java变量的声明规则与Scanner的应用
  • 算法训练营day44 动态规划⑪ 1143.最长公共子序列、1035.不相交的线、53. 最大子序和、392.判断子序列
  • BGP实验
  • (三)全栈(部署)
  • 数学建模——回归分析
  • 解决 Linux 下 “E: 仓库xxx没有数字签名” 问题