在 spring boot の宣言的トランザクションでは、一度に 1 つの TransactionManager のみを指定できるため、デフォルトでは 1 つのメソッド内で mysql または mongo のいずれかのトランザクションのみをサポートします。しかし、日常業務では、しばしば 1 つの業務内に mongo と mysql の両方が存在するため、この場合は mysql と mongo のトランザクションを同時にサポートする必要があります。そうしないと、mysql と mongo のデータが不一致になる可能性があります。
ChainedTransactionManager#
ChainedTransactionManager は Spring フレームワークのトランザクションマネージャの実装であり、複数のトランザクションマネージャを組み合わせてチェーン状のトランザクションマネージャを形成できます。しかし、注意すべきは、これはチェーン状の反応トランザクションマネージャであり、分散トランザクション(XA など)ではないということです。したがって、いくつかの複雑な状況ではトランザクションの一貫性を実現できません。したがって、ChainedTransactionManager は単純なトランザクションシナリオのみをサポートします。
@Configuration
@Slf4j
/**
* トランザクション管理
* mongoとmysqlのトランザクションを統合
*/
public class TransactionConfig {
@Bean
@Primary //mysqlトランザクションマネージャ デフォルトのトランザクションマネージャ
public JdbcTransactionManager mysqlTransactionManager(DataSource dataSource) {
return new JdbcTransactionManager(dataSource);
}
@Bean(name = "mongoTransactionManager")
public MongoTransactionManager mongoTransactionManager(MongoDatabaseFactory factory) {
return new MongoTransactionManager(factory);
}
@Bean(name = "chainedTransactionManager")
public ChainedTransactionManager chainedTransactionManager(JdbcTransactionManager jdbcTransactionManager, @Qualifier("mongoTransactionManager") MongoTransactionManager mongoTransactionManager) {
return new ChainedTransactionManager(jdbcTransactionManager,mongoTransactionManager);
}
}
ここでは 3 つの TransactionManager を設定しており、以降は具体的な業務に応じて @Transactional で使用する TransactionManager を指定できます。
@Transactional() //ここではデフォルトでmysqlのTransactionManager
public void methodA() {}
@Transactional(value = "mongoTransactionManager")
public void methodA() {}
@Transactional(value = "chainedTransactionManager")
public void methodA() {}
しかし、spring 公式は 2020 年 11 月に ChainedTransactionManager を @Deprecated としてマークし始めました。具体的な理由はhttps://github.com/spring-projects/spring-data-commons/issues/2232を参照してください。
すでに廃止されていますが、単純な状況のトランザクション処理をサポートしています。