实例程序技术架构如下:

交互流程如下:

1、请求bank1进行转账,传入转账金额。

2、bank1减少金额,调用bank2,传入转账金额。

搭建Demo工程

demo工程的Git地址:https://gitee.com/SX-Code/dtx-seata-demo

demo工程搭建教程: Seata实现分布式事务

Seata执行流程

要点说明:
1、每个RM使用DtaSourceProxy连接数据库,其目的是使用ConnetionProxy,使用数据源和数据连接代理的目的就是在第一阶段将undo_log和业务数据放在一个本地事务提交,这样就保存了只要有业务操作就一定有undo_log。

2、在第一阶段undo_log中存放了数据修改前和修改后的值,为事务回滚作好准备,所以第一阶段完成就已经将分支事务提交,也就释放了锁资源。

3、TM开启全局事务开始,将XID全局事务id放在事务上下文中,通过feign调用也将XID传入下游分支事务,每个分支事务将自己的BranchID分支事务ID与XID关联。

4、第二阶段全局事务提交,TC会通知各个分支参与者提交分支事务,在第一阶段就已经提交了分支事务,这里各参与者只需要删除undo_log即可,并且可以异步执行 ,第二阶段很快可以完成。

5、第二阶段全局事务回滚,TC会通知各个分支参与者回滚分支事务,通过 XID 和BranchID 找到相应的回滚日志,通过回滚日志生成反向的SQL并执行,以完成分支事务回滚到之前的状态,如果回滚失败则会重试回滚操作。

细节说明:

  • TM 请求 TC 开启一个全局事务。TC 会生成一个 XID 作为该全局事务的编号。

    XID,会在微服务的调用链路中传播,保证将多个微服务的子事务关联在一起。

  • RM 请求 TC 将本地事务注册为全局事务的分支事务,通过全局事务的 XID 进行关联。

  • TM 请求 TC 告诉 XID 对应的全局事务是进行提交还是回滚。

  • TC 驱动 RM 们将 XID 对应的自己的本地事务进行提交还是回滚。