第二阶段 异步删除分支 UndoLog
如果一阶段成功,则 TC
会通知客户端 RM
进行第二阶段的提交工作,这部分代码最终实现位于 AsyncWorker
类中的 branchCommit
方法。
1.分支信息,会插入到内存中的异步队列Async_commit_buffer
2. 插入 ASYNC_COMMIT_BUFFER 之后,AsyncWorker 类中会有一个定时任务,从队列中取出分支提交信息 Phase2Context,将其中的 xid 和 branchId 提取出来生成 DELETE SQL 语句,删除本地数据库中存储的相应的 UndoLog。下面是该定时任务的关键方法 doBranchCommits 的实现:
3.如果内存队列不为空,就poll方法获取出分支信息commitContext,然后获取对应的contextsGroupedByResourceId
存储在mappedContexts
4.继续从分支信息中获取xid和branchId,然后匹配出第一阶段生成的undoLog,调用batchDelete批量删除
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
二阶段生成反向 SQL 回滚,
1.获取对应的dataSourceProxy
2.根据xid和branchId 查询undoLog表,获取对应的undoLog
3.先查询出结果集rs,获取出rollback_info,转化为字节数组,反序列化成对象
4.buildUndoSQL() 构建对应的sql,也是分成delete, insert和update
5.下面我们以 DELETE
为例分析一下 MySQLUndoDeleteExecutor
类的 buildUndoSQL
方法的实现,如果一阶段已经删除了某行数据,那么二阶段补偿自然需要构造一个 INSERT
语句将被删除的行重新插入。
insert,需要构造对应的delete的sql语句