Seata AT模式详解(底层原理、底层流程图、Java代码示例等)
一、AT模式核心架构
-
三层架构:
- TM(Transaction Manager):事务管理器,负责开启/提交/回滚全局事务
- RM(Resource Manager):资源管理器,管理分支事务资源
- TC(Transaction Coordinator):事务协调器,维护全局事务状态
-
关键组件:
- 全局事务ID(XID):唯一标识整个分布式事务
- 分支事务ID(Branch ID):标识每个分支事务
- undo_log表:记录操作前的数据状态,用于自动回滚
二、AT模式底层原理详解
1. 第一阶段(Prepare阶段)
-
TM开启全局事务:
- 通过
@GlobalTransactional
注解触发 - TM生成全局事务ID(XID)并传播到所有参与服务
- 通过
-
RM执行SQL并记录undo_log:
- RM拦截业务SQL(通过Seata的DataSourceProxy实现)
- 执行SQL前记录undo_log:
- 解析SQL语句
- 记录操作前的数据状态(旧值)
- 将undo_log写入数据库的undo_log表
- 执行实际业务SQL
-
RM向TC报告执行结果:
- RM将执行结果(成功/失败)报告给TC
- TC记录分支事务状态
2. 第二阶段(Commit/Rollback阶段)
-
TC决定事务结果:
- 根据所有分支事务的执行结果决定全局事务状态
- 如果所有分支事务都成功,则决定提交
- 如果有分支事务失败,则决定回滚
-
RM执行提交或回滚:
- 提交阶段:
- RM收到TC的提交指令
- 直接提交本地事务(因为undo_log已记录,无需额外操作)
- 回滚阶段:
- RM收到TC的回滚指令
- 根据undo_log表中的记录执行回滚:
- 解析undo_log中的旧值
- 执行反向SQL(将数据恢复到操作前的状态)
- 删除对应的undo_log记录
- 提交阶段:
3. 关键技术实现
-
SQL拦截与解析:
- Seata通过DataSourceProxy拦截所有数据库操作
- 使用SQL解析器解析SQL语句,识别操作类型(INSERT/UPDATE/DELETE)
- 解析WHERE条件,确定受影响的行
-
undo_log生成:
- 对于UPDATE操作:
- 记录旧值(操作前的数据状态)
- 记录新值(操作后的数据状态)
- 对于INSERT操作:
- 记录插入的数据(作为回滚时的删除依据)
- 对于DELETE操作:
- 记录删除的数据(作为回滚时的插入依据)
- 对于UPDATE操作:
-
事务传播机制:
- XID通过ThreadLocal传递
- 在远程调用时通过RPC框架(如Dubbo、Feign)传递XID
- 确保同一全局事务的所有分支使用相同的XID
-
分支事务管理:
- 每个分支事务有唯一的Branch ID
- TC维护全局事务与分支事务的映射关系
- RM向TC报告分支事务的执行状态
三、AT模式底层流程图解
四、AT模式底层关键点
-
undo_log表结构:
- 包含以下关键字段:
id
:主键branch_id
:分支事务IDxid
:全局事务IDcontext
:上下文信息rollback_info
:undo_log内容(记录旧值)log_status
:日志状态(0-正常,1-已提交,2-已回滚)log_created
:创建时间log_modified
:修改时间
- 包含以下关键字段:
-
SQL解析与回滚:
- Seata内置SQL解析器支持多种数据库(MySQL、Oracle、PostgreSQL等)
- 回滚时根据undo_log中的旧值执行反向操作:
- UPDATE → 执行反向UPDATE
- INSERT → 执行DELETE
- DELETE → 执行INSERT
-
事务传播机制:
- XID通过ThreadLocal传递,确保同一线程内的所有操作使用相同的XID
- 在远程调用时,XID通过RPC框架传递:
- Dubbo:通过隐式参数传递
- Feign:通过HTTP头传递
-
性能优化:
- undo_log表采用异步清理机制
- 使用连接池减少数据库连接开销
- 批量操作时优化undo_log记录方式
五、AT模式Java代码示例
// 业务服务类
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
// 使用@GlobalTransactional开启全局事务
@GlobalTransactional
public void createOrder(Order order) {
// 1. 创建订单
orderMapper.insert(order);
// 2. 扣减库存(调用远程服务)
inventoryService.reduceStock(order.getProductId(), order.getNum());
// 3. 扣减优惠券(调用远程服务)
couponService.useCoupon(order.getCouponId());
}
}
// 库存服务(远程调用)
@Service
public class InventoryService {
@Autowired
private InventoryMapper inventoryMapper;
public void reduceStock(Long productId, Integer num) {
// 扣减库存
inventoryMapper.reduceStock(productId, num);
}
}
// 优惠券服务(远程调用)
@Service
public class CouponService {
@Autowired
private CouponMapper couponMapper;
public void useCoupon(Long couponId) {
// 使用优惠券
couponMapper.useCoupon(couponId);
}
}
六、AT模式底层优势
-
零侵入性:
- 业务代码无需修改,只需添加
@GlobalTransactional
注解 - Seata自动处理分布式事务
- 业务代码无需修改,只需添加
-
自动补偿:
- 基于undo_log表自动回滚
- 无需开发者编写回滚逻辑
-
高性能:
- 相比传统2PC,AT模式性能更高
- 减少了网络通信和锁竞争
-
强一致性:
- 保证分布式事务的强一致性
- 适用于对数据一致性要求高的场景
七、AT模式底层注意事项
-
数据库配置:
- 确保数据库支持Seata的AT模式
- 配置数据源代理(使用Seata的DataSourceProxy)
-
undo_log表:
- Seata会自动创建undo_log表
- 不要手动修改该表
-
异常处理:
- 捕获业务异常,Seata会自动回滚
- 不要捕获Seata的异常
-
性能优化:
- 减少远程调用次数
- 合理设计事务边界
AT模式是Seata分布式事务方案中最常用的模式,其底层通过SQL拦截、undo_log记录和自动回滚机制,实现了对业务代码零侵入的强一致性分布式事务。