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事务,也能更快的去排查跟定位问题。 如果你还有其他问题或想了解更多,欢迎留言交流! 😊

相关推荐
好好沉淀5 小时前
1.13草花互动面试
面试·职场和发展
阿蒙Amon8 小时前
C#每日面试题-常量和只读变量的区别
java·面试·c#
程序员小白条8 小时前
面试 Java 基础八股文十问十答第八期
java·开发语言·数据库·spring·面试·职场和发展·毕设
xlp666hub10 小时前
Linux 设备模型学习笔记(1)
面试·嵌入式
南囝coding11 小时前
CSS终于能做瀑布流了!三行代码搞定,告别JavaScript布局
前端·后端·面试
踏浪无痕11 小时前
Go 的协程是线程吗?别被"轻量级线程"骗了
后端·面试·go
一只叫煤球的猫12 小时前
为什么Java里面,Service 层不直接返回 Result 对象?
java·spring boot·面试
求梦82012 小时前
字节前端面试复盘
面试·职场和发展
C雨后彩虹13 小时前
书籍叠放问题
java·数据结构·算法·华为·面试
码农水水14 小时前
中国电网Java面试被问:流批一体架构的实现和状态管理
java·c语言·开发语言·面试·职场和发展·架构·kafka