SEATA分布式事务AT模式如何实现处理?
摘要:SEATA的AT模式和XA模式一样,也是2阶段提交,但是AT模式没有利用数据库的XA协议,如下所示: 从上面的图可以看到,seata AT 模式分为以下5个步骤: ①、TM(事务管理器) 开启全局事务; ②、RM 向 TC(事务协调者) 注
SEATA的AT模式和XA模式一样,也是2阶段提交,但是AT模式没有利用数据库的XA协议,如下所示:
从上面的图可以看到,seata AT 模式分为以下5个步骤:
①、TM(事务管理器) 开启全局事务;
②、RM 向 TC(事务协调者) 注册分支事务;
③、RM(资源管理器,也就是要访问数据库的进程或线程)记录undo-log(数据快照);
④、RM执行业务sql并提交,并向TC报告状态;
⑤、TC根据所有RM分支报告的状态来决定本次全局事务中的各个RM是要Async Commit(异步提交)或者Auto Rollback(自动回滚),异步提交和自动回滚都需要以不同的方式对步骤③中记录的undo-log(数据快照)进行操作(异步提交的话删除undo-log,自动回滚的话根据undo-log的记录进行回滚)
一、数据源代理
seata 中的 AT 模式也是使用数据源代理来实现的,如下所示:
DataSourceProxy、ConnectionProxy、StatementProxy的UML关系图,如下所示:
AbstractDataSourceProxy.class和 DataSourceProxy.class的部分源码
...省略导包代码...
public abstract class AbstractDataSourceProxy implements SeataDataSourceProxy {
...省略部分代码...
protected DataSource targetDataSource;
...省略部分代码...
}
...省略导包代码...
public class DataSourceProxy extends AbstractDataSourceProxy implements Resource {
//创建ConnectionProxy
...省略部分代码...
@Override
public ConnectionProxy getConnection() throws SQLException {
Connection targetConnection = targetDataSource.getConnection();
return new ConnectionProxy(this, targetConnection);
}
@Override
public ConnectionProxy getConnection(String username, String password) throws SQLException {
Connection targetConnection = targetDataSource.getConnection(username, password);
return new ConnectionProxy(this, targetConnection);
}
...省略部分代码...
}
ConnectionProxy.class和 AbstractConnectionProxy.class的部分源码
...省略导包代码...
public class ConnectionProxy extends AbstractConnectionProxy {
...省略部分代码...
//提交SQL
@Override
public void commit() throws SQLException {
try {
lockRetryPolicy.execute(() -> {
doCommit();
return null;
});
} catch (SQLException e) {
if (targetConnection != null && !getAutoCommit() && !getContext().isAutoCommitChanged()) {
rollback();
}
throw e;
} catch (Exception e) {
throw new SQLException(
