Seata AT模式分布式事务源码解析
2025-06-10 16:33:35 0 举报
Seata AT模式分布式事务源码解析
作者其他创作
大纲/内容
根据事务xid 删除 lock_table 锁数据
23. 执行流程同库存一样
成功
成功(影响的行数:1)
删除成功
19. 操作成功
row_key:jdbc:mysql://127.0.0.1:3306/demo^^^stock_tbl^^^77
结束
Order Service
20. Feign 调用创建订单(Header:TX_XID=10.103.1.48:8091:5296890)
提交回滚事务
RM(Stock DB)
什么是 seata ? 解决分布式事务的技术;需要一个额外的 seata jar 服务支持
2. 注册全局事务(GlobalBeginRequest)
RootContext.bind(xid);
25. 所有操作完成
2. 将rollback_info 字节转换为对象(branchUndoLog)
1. 随机生成事务xid2. 往数据表 global_table 插入一条数据;
17. 生成 undo_log
客户端
12. 生成锁数据 stock_tbl:77 请求 TC 判断是否被加锁
34. 库存扣减成功
RPC 发起调用 库存服务 doBranchRollback
执行业务逻辑抛出异常情况
29. 根据 XID 循环删除 lock_table
TM (Stock Service)
branchUndoLog包含 before image 和 after image的字段值0 = {Field@23436} \
RPC 发起请求生成全局事务xid
28. 根据 XID 循环删除 branch_table
修改 global_table 状态update global_table set status = 4 where xid = '10.103.1.48:8091:529689' and status = 1
13. 查询 lock_table 锁表,判断是否被其他线程使用select * from lock_table where row_key in ( ? )
32. 异步线程删除 undo_log
5 次重试机制 RPC 调用 TC 服务
有多种模式,默认 AT 模式
rollback_info 非常重要,存储before 和 after 镜像插入时会将 before 和 after 镜像存入类,且转换字节后插入
修改 lock_table 状态update lock_table set status = 1 where xid = '10.103.1.48:8091:529689
TC Seata 服务
TC 数据表global_tablebranch_tablelock_table
成功(事务XID:10.103.1.48:8091:5296890)
DELETE FROM undo_log WHERE context = 'branchId=529689' AND xid = '10.103.1.48:8091:529689'
1、AT 模式 执行流程
5. 绑定 XID 到线程上下文
7. 执行 deductStock(库存)
Stock DB
8. 获取代理连接 (ConnectionProxy)
UPDATE account_tbl SET money = 10000 WHERE id = 86
row_key
22. 执行业务逻辑
31. 全局事务提交成功
POST /order/create
4. 返回(事务XID:10.103.1.48:8091:5296890)
和普通事务处理模式差不多,会使用 try 判断是否抛出异常,异常:回滚;正常:结束
26. 提交全局事务
for 循环操作
3. INSERT INTO font color=\"#e74f4c\
6. TM 执行业务逻辑
1. 获取 undp_log 日志表记录SELECT * FROM undo_log WHERE branch_id = 529689 AND xid = '10.103.1.48:8091:529689' FOR UPDATE
30. 根据 XID 循环删除 global_table
21. 绑定 XID(加入全局事务)
返回库存信息
24. 创建订单成功
无异常
Stock Service
2)执行后保存对应的字段值(后续回滚操作)
根据事务xid 删除 branch_table 分支数据
10. update stock_tbl set count = 98 WHERE id = 77(执行真正业务 SQL)
TC 根据定时任务再批量删除状态为4的 global_table 数据
1. @GlobalTransaction 方法调用
4. 删除 undo_table 数据
1)生成之前镜像的 SQL,且 FOR UDPATE 对该id记录行加锁
发起 Fegin 时,会有SeataFeignRequestInterceptor拦截器会把RootContext.getXID()写入到头信息中
返回数据
3. 将 after image 字段 解析到 SQL并执行还原操作;本质是补偿机制
delete from branch_table where xid = ? and branch_id = ?
请求来到服务时,会先执行 SeataHandlerInterceptor 拦截器,preHandle方法会把头信息 XID 放入 RootContext.bind(rpcXid) 中;有了全局事务 XID 后续都会是全局事务如果没有则是普通事务如果有他会使用 seata代理后的conn去执行,就会判断 RootContext 中是否有 XID 做不同的操作
16. 返回 BranchId:10001
33. 事务完成
0 条评论
下一页