ShardingSphere 中的分布式事务

以配置 XA 事务为例,查看整体流程

transaction rule 的初始化

1
2
3
4
5
6
7
8
9
public TransactionRule(final TransactionRuleConfiguration ruleConfig, final Map<String, ShardingSphereDatabase> databases) {
    configuration = ruleConfig;
    defaultType = TransactionType.valueOf(ruleConfig.getDefaultType().toUpperCase());
    providerType = ruleConfig.getProviderType();
    props = ruleConfig.getProps();
    // 创建 transactionManager 
    resource = new AtomicReference<>(createTransactionManagerEngine(databases));
    attributes = new RuleAttributes();
}

XA transactionManager 内部管理着 XA DataSource 也一并初始化(mysql 提供的 com.mysql.cj.jdbc.MysqlXADataSource)

1
2
3
4
5
public final class XAShardingSphereTransactionManager implements ShardingSphereTransactionManager {
    
    private final Map<String, XATransactionDataSource> cachedDataSources = new CaseInsensitiveMap<>();
    
    private XATransactionManagerProvider xaTransactionManagerProvider;

以 insert 为例,查看全卷事务如何管理

其实就是使用初始化时使用的 transactionManager 来 begine 和 commit.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
private <T> T doExecuteWithImplicitCommitTransaction(final ImplicitTransactionCallback<T> callback) throws SQLException {
        T result;
        // 获取上述初始化的 xatransactionManagerEngine
        BackendTransactionManager transactionManager = new BackendTransactionManager(databaseConnectionManager);
        try {
            transactionManager.begin();
            result = callback.execute();
            transactionManager.commit();
            // CHECKSTYLE:OFF
        } catch (final Exception ex) {
            // CHECKSTYLE:ON
            transactionManager.rollback();
            String databaseName = databaseConnectionManager.getConnectionSession().getDatabaseName();
            throw SQLExceptionTransformEngine.toSQLException(ex, ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getDatabase(databaseName).getProtocolType());
        }
        return result;
    }

总结

从 shardingSphere 角度来看,其实对于分布式事务而言,主要提供了一些封装和框架流程的调用。内部的 transactionManager 实际由其它开源组件提供。 例如 narayana 和 atomics。

narayana 和 atomics 其实提供了 transactionManager 角色和功能, shardingSphere 做了一些封装。 各个数据库,承担的是 resourceManager 角色和功能。 TM 发起 prepare, RM 准备提交,达到万事俱备只欠东风的状态。 TM 发现大家都完成了之后,发起提交命令,如果有人失败了,那么就整体回滚。

updatedupdated2024-05-132024-05-13