




【解释】


【解释】在上面这3个参数中,tableMeta表元数据是最重要的,在AT模式的很多处理环节中都要用到它。

【解释】


【解释】getCacheKey方法里面逻辑比较简单,主要就是拼装resourceId和特殊处理后的tableName









【解释】


【解释】





【解释】由于DataSourceProxy是DataSource接口的一个实现,这使得DataSourceProxy类可以分析要执行的SQL语句,以及生成对应的回滚SQL语句。

【解释】



【解释】


【解释】

【解释】该接口用来接收TC发送来的请求,其中包含了:二阶段的分支事务提交请求、二阶段的分支事务回滚请求。

【解释】接口用于RM主动发送到TC的事务处理请求,例如:分支事务注册、事务状态上报、查询全局锁。



在方法resource.getBranchType()中,resource就是DataSourceProxy实例,它返回的分支类型是AT,如下图所示:

在getResourceManager(...)方法中,用于获取资源管理器ResourceManager对象,通过入参branchType=AT,我们可以获得AT的资源管理器为DataSourceManager。如下图所示:


那resourceManagers是在哪个地方初始化的呢?我们来看一下ResourceManager的构造方法

下面我们来看一下EnhancedServiceLoader.loadAll(...)方法,它通过SPI机制加载META-INF/services/io.seata.core.model.ResourceManager中配置的ResourceManager的具体实现类,如下所示:

方法DataSourceManager.registerResource(Resource resource)用于注册资源,当TC收到资源注册请求后,会把客户端连接与resourceGroupId和resourceId在内存中建立对应关系。在推进二阶段提交或二阶段回滚操作时,可以根据resourceGroupId和resourceId找到相应的客户端连接并发送请求。这种机制保证了二阶段操作的高可用性。其源码如下所示:

4.4.3> ConnectionProxy


【解释】如上面截图中标注的步骤1和步骤2,进行详细的源码解析。

【解释】

【解释】每次执行sleep方法,都会促使lockRetryTime减1,如果值小于0,则不执行sleep操作了,直接抛出异常。




【解释】processGlobalTransactionCommit()方法中包含3个重要的步骤(我们随后会分别解析一下),分别为:

DefaultResourceManager的branchRegister(...)方法用于分支注册操作,源码如下所示:

AbstractResourceManager的branchRegister(...)方法逻辑如下所示:


【解释】





















【解释】随着代码的深入跟踪,我们看到最后是从nameToDefinitionsMap通过查询key是activateName来获得UndoLogParser的实现子类。



【解释】从上面的源码中我们可以看到,如果我们要获取一个UndoLogParser的某个子类的时候,可以通过指定serviceName的方式,例如:serviceName=“jackson”,那么,再根据io.seata.rm.datasource.undo.UndoLogParser文件中配置的所有UndoLogParser实现类去查找。根据每个实现类的@LoadLevel注解中的name属性,来进行匹配。



该类中很多方法都是直接调用targetStatement实现的,代理类没有做额外的工作,如下所示:




【解释】






【解释】



【解释】

【解释】

【解释】从上面代码中的逻辑我们可以看出来,针对于已经开启自动提交的连接,会先关闭自动提交,然后调用的实际执行逻辑是executeAutoCommitFalse方法,执行完毕后,会手动进行提交操作,并且最后开启自动提交。

【解释】目前只有MySQL数据库支持多个主键。对于其他数据库,如果表存在多主键,则不允许使用AT模式,但是可以使用TCC、Saga或XA模式。


【解释】


【解释】

【解释】





其中,将合并后的事务日志保存到连接上下文ConnectionContext中

【解释】

【解释】

【解释】在本地事务提交之前,通过TC注册分支事务。


【解释】创建完二阶段上下文后,将二阶段上下文添加到CommitQueue中,随即就返回二阶段已提交状态了。此阶段采取的是异步方式,而非同步阻塞的方式。

scheduledExecutor是每秒执行一次的定时任务线程池,如下所示:

【解释】调用offer方法将Phase2Context提交到提交队列中。如果返回false,则说明commitQueue已经满了。


【解释】





【解释】在还原前,要先校验“脏写”,即:对比后镜像和数据库中的当前值。



【解释】





【解释】如果业务SQL语句是insert语句,则它的回滚语句就是delete语句,删掉在一阶段中插入的行。

【解释】

【解释】