04-深入解析 Spring 事务管理原理及源码

深入解析 Spring 事务管理原理及源码

Spring 事务管理(Transaction Management)是企业级应用开发中至关重要的功能之一,它确保数据操作的 原子性、一致性、隔离性、持久性(ACID)

本篇博客将从 Spring 事务的基本概念 开始,深入 Spring 事务的实现机制 ,并对 @Transactional 注解的底层执行流程 进行源码级解析。


1. 事务的基本概念

在数据库操作中,事务是一个逻辑操作单元,必须满足 ACID 四大特性:

特性 说明
原子性(Atomicity) 事务内的所有操作要么全部成功,要么全部失败
一致性(Consistency) 事务执行后,数据库从一个一致性状态转换到另一个一致性状态
隔离性(Isolation) 并发事务相互隔离,防止数据不一致
持久性(Durability) 事务提交后,数据永久保存到数据库

⚙️ 2. Spring 事务的核心组件

Spring 通过 声明式事务编程式事务 来管理数据库事务。

2.1 Spring 事务的核心接口

组件 作用
PlatformTransactionManager 事务管理器接口
DataSourceTransactionManager 适用于 JDBC 的事务管理器
JpaTransactionManager 适用于 JPA(Hibernate)的事务管理器
TransactionDefinition 事务的定义,包括隔离级别、传播行为等
TransactionStatus 事务的当前状态

3. @Transactional 注解解析

Spring 通过 @Transactional 注解实现 声明式事务,常见用法如下:

java 复制代码
@Service
public class OrderService {

    @Transactional
    public void createOrder() {
        // 事务开始
        orderDao.insertOrder();
        paymentDao.processPayment(); // 若失败,事务回滚
        // 事务提交
    }
}

3.1 @Transactional 支持的属性

属性 说明
propagation 事务传播行为
isolation 事务隔离级别
timeout 事务超时时间
readOnly 是否为只读事务
rollbackFor 指定哪些异常会触发回滚

4. Spring 事务管理的源码解析

Spring 事务管理的核心是通过 AOP(面向切面编程) 来实现的,底层依赖于 TransactionInterceptor 和 PlatformTransactionManager 来实现事务的创建、提交、回滚等操作。

4.1 事务的创建与提交流程

1️⃣ @Transactional 代理拦截

Spring 事务使用 AOP 代理 来拦截标注了 @Transactional 注解的方法,并通过 TransactionInterceptor 来处理事务的启动、提交和回滚。具体如下:

java 复制代码
public Object invoke(MethodInvocation invocation) throws Throwable {
    return transactionInterceptor.invokeWithinTransaction(
        invocation.getMethod(), targetClass, invocation::proceed
    );
}

2️⃣ 获取事务管理器并创建事务

事务管理器(如 DataSourceTransactionManager)负责管理事务。在 doBegin() 方法中会启动一个新的事务:

java 复制代码
@Override
protected void doBegin(Object transaction, TransactionDefinition definition) {
    Connection conn = DataSourceUtils.getConnection(dataSource);
    conn.setAutoCommit(false); // 关闭自动提交,开启事务
}

3️⃣ 执行业务逻辑

当事务开始后,Spring 会执行业务方法(invocation.proceed())。如果在业务逻辑执行过程中出现异常,则会触发回滚。

4️⃣ 提交或回滚事务

当方法执行完成后,事务会根据是否抛出异常来决定提交还是回滚:

java 复制代码
@Override
protected void doCommit(DefaultTransactionStatus status) {
    status.getConnectionHolder().getConnection().commit();
}

@Override
protected void doRollback(DefaultTransactionStatus status) {
    status.getConnectionHolder().getConnection().rollback();
}

5. 事务的传播机制

Spring 事务支持 7 种传播行为,用于控制当前事务如何传播到嵌套事务中。以下是最常用的几种传播行为及其实际应用:

传播行为实例

1️⃣ REQUIRED(默认行为

如果当前存在事务,则加入事务;如果当前没有事务,则新建事务。例如:

java 复制代码
@Transactional(propagation = Propagation.REQUIRED)
public void method1() {
    // 当前存在事务,将加入该事务
}

如果 method1() 中调用了一个没有声明事务的方法 method2(),method2() 会加入到 method1() 的事务中。

2️⃣ REQUIRES_NEW

当前方法总是会新建一个事务,暂停当前事务。例如:

java 复制代码
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void method1() {
    // 新建一个事务,当前事务会被挂起
}

当 method1() 执行时,它会暂停外部事务,并在自身内部创建一个新的事务。

3️⃣ NESTED

在当前事务中创建一个嵌套事务。嵌套事务可以独立提交或回滚,但会共享外部事务的连接。例如:

java 复制代码
@Transactional(propagation = Propagation.NESTED)
public void method1() {
    // 创建一个嵌套事务
}

嵌套事务在提交时不会影响外部事务,但可以独立回滚。

组合后的效果

REQUIRED + REQUIRES_NEW:会在外部事务的基础上创建新的事务,外部事务挂起,内部事务完成后恢复外部事务。

REQUIRED + NESTED:如果外部事务提交,嵌套事务也会提交;若外部事务回滚,嵌套事务也会回滚。

通过以上,应该可以很快了解Spring事务,也能更快的去排查跟定位问题。

如果你还有其他问题或想了解更多,欢迎留言交流! 😊

相关推荐
东风破_2 小时前
danci 2:创建的单词书到底存在哪里?从 Supabase 一路理解 ORM、Drizzle 和 RLS
数据库·后端·node.js
微尘寒风2 小时前
【Git】的安装和使用
java·git
东风破_2 小时前
danci 项目(三):从 JSON 数据到 AI Coding,真实项目里的数据清洗、Prompt 和工程规范
前端·后端·node.js
y = xⁿ2 小时前
DeepSeek Harness 学习日记:关于Agent接口,工具调用的底层实现
android·java·学习
东风破_3 小时前
danci 项目(一):从需求到架构,一个单词学习系统为什么会这样设计
前端·后端·node.js
侧耳倾听1113 小时前
jwt使用简介
java·jwt
橙子家3 小时前
OSS 文件上传的几个风险点和解决方案
数据库
顶点多余4 小时前
那些在算法中适合巩固的知识点---1
java·前端·算法
AI人工智能+电脑小能手4 小时前
大白话说Java设计模式-46-责任链模式(业务实战篇)
java·设计模式·责任链模式·风控校验·servlet filter·spring interceptor·链式处理
jay神4 小时前
【计算机毕业设计】基于SpringBoot的程序教学辅助系统
java·前端·vue.js·spring boot·后端·毕业设计·课程设计