AT 实现客户端部分,主要在rm-dataSource中
重点实现还是在statementProxy
查看一个execute方法,首先会调用executeTemplate.execute方法
1、首先判断,如果当前不是全局事务,并且没有全局锁,那么就直接execute执行这个sql,返回对应的结果即可
2、如果当前处于全局事务,就先判断SQL的类型,创建不同类型的executor,如下图
3.创建好对应sql类型的executor后,就调用execute方法执行,实现都是在BaseTransactionalExecutor中
3.1 如果在全局事务中,需要绑定xid
3.2 如果有全局锁,也需要设置对应的全局锁
3.3 调用doExecute方法执行,实现在AbstractDMLBaseExecutor 中,会调用到executeAutoCommitTrue
3.3.1 connectionProxy.setAutoCommit(false); 先将自动提交关闭,只允许手动提交
3.3.2 进入一个while(true)的无限循环,执行executeCommitFalse方法
1.beforeImage(), 先查询操作数据前的快照
2.调用statementCallback.execute 执行sql,
3. afterImage(beforeImage); 查询操作数据后的快照
4. prepareUndoLog:根据1,3 构建出undoLog,用于回滚
3.4 执行完后,调用commit,提交本地事务,然后break跳出循环
3.5 如果全局锁冲突,代表别的事务已经获取到要修改数据的全局锁,则执行回滚
4.继续深入看下commit,connectionProxy.commit()的具体实现
5. processGlobalTransactionCommit 执行全局事务的commit
5.1 首先是register(), RM注册分支事务
5.2 如果当前有回滚日志undoLog ,就把undoLog存储到mysql或者oracle
5.3 targetConnection.commit(); 提交事务
至此 第一阶段提交实现完成
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++