seata源码分析之-AT模式客户端分析4
- RM的大致执行流程图
- ConnectionProxy之processGlobalTransactionCommit
-
- ConnectionProxy之register注册分支事务
- ConnectionProxy之recognizeLockKeyConflictException处理锁冲突
- UndoLogManager之flushUndoLogs写入回滚日志
- ConnectionProxy之report报告事务状态
- ConnectionProxy之rollback异常回滚
- TC通知提交成功或者回滚
-
- DataSourceManager的branchCommit接受TC分支提交成功的处理
- DataSourceManager的branchRollback接受TC分支回滚的处理
-
- AbstractUndoLogManager的undo
RM的大致执行流程图
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyVGduV2YfNWawNCM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2cs0TP310dFRVTzcGVPh3aXp1Mk1mYoR2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLxkTM1EzMyIjMxEjMwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
ConnectionProxy之processGlobalTransactionCommit
上篇分析到这里,要进行全局事务的提交了,当然首先得要注册到TC上去,因为我们是属于一部分事务即分支事务,这里还有个异常捕获,其实就是说可能已经有其他事务拿到整个行锁了,那就要等待,就跟分布式锁一样,随后就进行回滚日志的写入,最后整体提交,所以这里执行
sql
语句和回滚日志写入是一个事务内的,保证了原子性,只要提交成功了,那肯定有回滚事务,后续就可以进行回滚。最后还会有报告状态,跟
TC
说下是成功了还是失败了:
ConnectionProxy之register注册分支事务
其实就是把当前分支事务注册到
TC
里去,如果成功的话就会返回一个分支
ID
,失败的话可能就是锁冲突或者说全局事务已经不存在了,因为
TC
那边有超时,超时就删除了。
ConnectionProxy之recognizeLockKeyConflictException处理锁冲突
如果是冲突异常的话,会抛出
LockConflictException
,捕获后会进行重试,但是也可能是其他的,比如我们这里的,说事务不存在了,可能是完成了,但是其实我们是超时了,说明
TC
那边超时删除了,然后我们又拿着这个事务去查。
前面的冲突异常重试机制:
UndoLogManager之flushUndoLogs写入回滚日志
如果没有异常,就会封装一个回滚日志写入
undo_log
中,最后提交。
ConnectionProxy之report报告事务状态
如果写回滚日志或者事务提交出现问题都会进行失败报告给
TC
,当然成功也会。
ConnectionProxy之rollback异常回滚
如果发生了异常,就会进行回滚
TC通知提交成功或者回滚
上面说的是
RM
侧自己的处理,接下来说
TC
来通知我们提交或者回滚,一般都是TM触发的,所有事物都成功或者有问题回滚了,那么通知
TC
,
TC
在通知所有的
RM
。我们在前面说过,做
GlobalTransactionScanner
在初始化的时候会进行RM
的
初始化,会注册一些处理器,这里就有提交和回滚处理器:
DataSourceManager的branchCommit接受TC分支提交成功的处理
进过
netty
组件和处理器的分派,最终到
DataSourceManager
的
branchCommit
来进行处理。
其实他只是进行了入队,然后是异步处理,去删除回滚日志,至于
AsyncWorker
是什么,暂时不用关心,就当是一个异步任务,来进行回滚日志的删除用的。
DataSourceManager
初始化的时候会创建
AsyncWorker
,然后开启定时任务:
主要是进行批量删除,因为已经成功了,其他具体的细节自己可以去看:
DataSourceManager的branchRollback接受TC分支回滚的处理
如果是要回滚,就会调用回滚逻辑。
AbstractUndoLogManager的undo
里面是个死循环,就是说一定要进行回滚。
其中有对应的回滚执行器来进行回滚
dataValidationAndGoOn
方法里面会进行验证检查,是否需要回滚,是否有脏写:
回滚之后还需要将回滚日志删除,当然如果不存在的话可能是写入失败了,就会写入一条,来作为数据一致性的记录:
大致
RM
的流程就这样,具体有很多细节要自己去看,当然后面有时间也会提一些。
总结一下:
-
提交之前进行分支任务注册,如果是锁冲突就重试,其他的话就算失败了要进行回滚操作RM
- 如果提交成功伴随着回滚日志的写入,然后报告状态
- 如果收到
的提交成功,就进行回滚日志的异步删除TC
- 如果收到
的回滚,就进行回滚操作,也可能什么都不做,具体看前后镜像和现在数据的对比,最后要同步删除回滚日志或者写入一条回滚日志作为事务完成了的数据一致性的记录TC
今天就到这里了,希望对学习理解有帮助,大神看见勿喷,仅为自己的学习理解,能力有限,请多包涵。