事务

实战

Posted by Ekko on November 13, 2025

[TOC]


1
2
3
4
5
6
7
8
9
10
11
12
13
public enum TransactionPhase {
    // 事务即将提交但尚未提交
    BEFORE_COMMIT,
    // 事务已提交
    AFTER_COMMIT,
    // 事务已回滚
    AFTER_ROLLBACK,
    // 事务完成(无论提交还是回滚)
    AFTER_COMPLETION;

    private TransactionPhase() {
    }
}

Seata

2pc

3pc

tcc

XA

saga


Spring事务 - 核心接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 事务管理的核心入口
public interface PlatformTransactionManager {
    TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
    void commit(TransactionStatus status) throws TransactionException;
    void rollback(TransactionStatus status) throws TransactionException;
}

// 事务定义(传播行为、隔离级别、超时等)
public interface TransactionDefinition {
    int getPropagationBehavior();
    int getIsolationLevel();
    int getTimeout();
    boolean isReadOnly();
    String getName();
}

// 事务状态
public interface TransactionStatus {
    boolean isNewTransaction();
    boolean hasSavepoint();
    void setRollbackOnly();
    boolean isRollbackOnly();
    boolean isCompleted();
}

Spring事务 - 管理器

1
2
3
4
5
6
7
8
// JDBC 事务(最常用)
public class DataSourceTransactionManager implements PlatformTransactionManager

// JPA 事务  
public class JpaTransactionManager implements PlatformTransactionManager

// JTA 分布式事务
public class JtaTransactionManager implements PlatformTransactionManager

@Transactional

代理机制:Spring AOP 创建代理对象拦截方法调用

事务拦截:TransactionInterceptor 负责事务的开启、提交、回滚

事务管理:PlatformTransactionManager 抽象不同数据源的事务操作

资源绑定:通过 ThreadLocal 管理连接等事务资源

传播控制:根据传播行为决定事务的创建、加入、挂起等

同步回调:TransactionSynchronization 提供事务生命周期钩子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
    /*
    事务执行时间线:
    
    T0: TransactionInterceptor.invoke() 开始
        ↓
    T1: 获取 @Transactional 配置
        ↓  
    T2: 根据传播行为处理现有事务
        ↓
    T3: DataSourceTransactionManager.doBegin()
        - 获取数据库连接
        - 设置隔离级别、只读等
        - 关闭自动提交
        - 绑定连接到ThreadLocal
        ↓
    T4: 执行目标业务方法
        - userRepository.save(user)
        - 其他数据库操作
        ↓
    T5: 业务方法执行完成
        ↓
    T6: 提交事务 DataSourceTransactionManager.doCommit()
        ↓
    T7: 清理ThreadLocal资源
        ↓
    T8: 返回结果
    
    异常情况:
    T4: 业务方法抛出异常
        ↓
    T5: 回滚事务 DataSourceTransactionManager.doRollback()
        ↓  
    T6: 清理ThreadLocal资源
        ↓
    T7: 重新抛出异常
    */

本地事务表

其实还是一种弱一致性,通过最终对账的方式,保证最终一致性

通过定时任务或者其他方式,扫描 本地事务表,补偿重试机制。超过重试次数,告警人工兜底

本地事务表.png

RocketMQ 事务消息

RocketMQ 的事务消息,二阶段提交,仅仅是确保业务操作与消息发送的原子性(说简单点,就是保证消息一定发送成功)。其实还是弱一致性