一、在Seata的AT模式中,事务的提交也是分成了2阶段的
一阶段
1、RM
针对本次要执行的本地事务的SQL进行解析,得到SQL的类型、修改的表以及where条件等信息
2、RM
根据 SQL 解析的结果,先进行一次查询,根据查询结果生成相应的 before image 前置镜像(变更前数据快照)
3、执行SQL语句进行数据库变更
4、再查询一次变更后的记录,作为 after image 后置镜像(变更后的数据快照)
5、把 before/after image
以及业务 SQL 相关的信息组成一条回滚日志记录,插入到 undo log
表中
6、提交前,向 TC
注册分支,并申请表中本次需要修改的所有记录的排他锁
7、将业务数据的更新和前面生成的 undo log
一并提交
8、将本地事务的执行结果上报给 TC
二阶段
在一阶段,业务操作完成后,TM
向 TC
发起提交请求。TC
会发起投票请求,询问所有的 RM
是否可以提交事务
那么就会出现 2 种情况:
提交事务:
如果所有的 RM 都同意提交,说明他们此时他们的本地事务都已经执行成功了,那么TC就可以释放该全局事务的所有锁,然后异步调用RM清理 undo log
回滚事务:如果任一 RM 投票否决或者出现故障,那么就要协调事务进行回滚
1、通过 XID
和 Branch ID
查找到相应的 undo log
记录
2、会拿当前数据先跟 afterImage
进行比较,如果一致,执行第三步
如果不一致,则在比较一下当前数据是否 和 beforeImage
,如果一致性,说明未提交成功或者已经回滚了,则无需处理
如果不一致,那么说明有脏数据了,需要抛出异常,人工处理
3、根据 undo log
中的 beforeImage
和业务 SQL 的相关信息生成并执行回滚的语句
4、执行SQL并提交本地事务。并把本地事务的执行结果上报给 TC