In Spring Boot's declarative transactions, only one TransactionManager can be specified at a time, so by default, a method can only support transactions for either MySQL or MongoDB. However, in daily business scenarios, there are often cases where both MongoDB and MySQL are involved in a single business operation. In such cases, it is necessary to support transactions for both MySQL and MongoDB simultaneously; otherwise, inconsistencies between MySQL and MongoDB data may occur.
ChainedTransactionManager#
ChainedTransactionManager is a transaction manager implementation in the Spring framework that can combine multiple transaction managers into a chain of transaction managers. However, it is important to note that it is only a chained reactive transaction manager, not a distributed transaction (like XA). Therefore, in certain complex situations, it still cannot achieve transaction consistency. Thus, ChainedTransactionManager only supports simple transaction scenarios.
@Configuration
@Slf4j
/**
* Transaction management
* Integrating MongoDB and MySQL transactions
*/
public class TransactionConfig {
@Bean
@Primary // MySQL transaction manager, default transaction manager
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);
}
}
Here, three TransactionManagers are configured, and later, the specific TransactionManager can be specified in @Transactional based on the business requirements.
@Transactional() // The default here is MySQL's TransactionManager
public void methodA() {}
@Transactional(value = "mongoTransactionManager")
public void methodA() {}
@Transactional(value = "chainedTransactionManager")
public void methodA() {}
However, the Spring official team marked ChainedTransactionManager as @Deprecated in November 2020. The specific reason can be found at https://github.com/spring-projects/spring-data-commons/issues/2232.
Although it has been deprecated, it can still support transaction processing in simple cases.