[Three thousand questions about spring things] Spring configures multiple data sources vs. adding thing management to multiple data sources

There is a difference between configuring multiple data sources in Spring and adding transaction management to multiple data sources.
If you only need to use multiple data sources and do not need to manage things, you can do simple processing.

Configure multiple data sources in Spring

It is relatively easy to configure multiple data sources in Spring if there is no need for transaction management of the data sources.
According to the previous analysis of the processing of multiple transaction managers & amp; multiple data sources, we know that if MyBatis is used to operate DB, then only two steps are required to configure multiple data sources:
1. Define n data sources DataSource
2. Define the SqlSessionFactory based on DataSource (operate sql through MyBatis)

An example configuration of multiple data sources is as follows:

// Master data source configuration
@Configuration
@MapperScan(basePackages = "com.kvn.mapper.master", sqlSessionFactoryRef = "masterSqlSessionFactory")
public class MasterMybatisConfig {<!-- -->

    @Bean("master")
    @ConfigurationProperties(prefix = "spring.datasource.master")
    public DataSource masterDataSource() {<!-- -->
        return DataSourceBuilder.create().build();
    }
    
    @Bean("masterSqlSessionFactory")
    public SqlSessionFactory masterSqlSessionFactory(@Qualifier("master") DataSource dataSource) throws Exception {<!-- -->
        // set the data source
        MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
        mybatisSqlSessionFactoryBean.setDataSource(dataSource);
        // mapper's xml file location
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        String locationPattern = "classpath*:/mapper/master/*.xml";
        mybatisSqlSessionFactoryBean.setMapperLocations(resolver.getResources(locationPattern));
        // corresponding to the entity location of the database
        String typeAliasesPackage = "com.kvn.entity.master";
        mybatisSqlSessionFactoryBean.setTypeAliasesPackage(typeAliasesPackage);
        return mybatisSqlSessionFactoryBean.getObject();
    }
}

-------------------------------------------------- -------------------------------------------------- --------
-------------------------------------------------- -------------------------------------------------- --------

// Slave data source configuration
@Configuration
@MapperScan(basePackages = "com.kvn.mapper.slave", sqlSessionFactoryRef = "masterSqlSessionFactory")
public class SlaveMybatisConfig {<!-- -->

    @Bean("slave")
    @ConfigurationProperties(prefix = "spring.datasource.slave")
    public DataSource slaveDataSource() {<!-- -->
        return DataSourceBuilder.create().build();
    }
    
    @Bean("slaveSqlSessionFactory")
    public SqlSessionFactory masterSqlSessionFactory(@Qualifier("slave") DataSource dataSource) throws Exception {<!-- -->
        // set the data source
        MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
        mybatisSqlSessionFactoryBean.setDataSource(dataSource);
        // mapper's xml file location
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        String locationPattern = "classpath*:/mapper/master/*.xml";
        mybatisSqlSessionFactoryBean.setMapperLocations(resolver.getResources(locationPattern));
        // corresponding to the entity location of the database
        String typeAliasesPackage = "com.kvn.entity.slave";
        mybatisSqlSessionFactoryBean.setTypeAliasesPackage(typeAliasesPackage);
        return mybatisSqlSessionFactoryBean.getObject();
    }

}

Configure transaction management of multiple data sources in Spring

If you want to add the function of adding transaction management to the data source, then you need to add a transaction manager (TransactionManager) to each DataSource on the basis of multiple data source configurations, and at the same time, enable the interception of the @Transactional method.
Therefore, the steps to configure transaction management of multiple data sources are as follows:
1. Define n data sources DataSource
2. Define the SqlSessionFactory based on DataSource (operate sql through MyBatis)
3. Define the TransactionManager (things manager) based on DataSource
4. Use @EnableTransactionManagement to enable the interception of the @Transactional method

An example of transaction management configuration for multiple data sources is as follows:

// Master data source configuration
@Configuration
@MapperScan(basePackages = "com.kvn.mapper.master", sqlSessionFactoryRef = "masterSqlSessionFactory")
public class MasterMybatisConfig {<!-- -->

    @Bean("master")
    @ConfigurationProperties(prefix = "spring.datasource.master")
    public DataSource masterDataSource() {<!-- -->
        return DataSourceBuilder.create().build();
    }

    /**
     * Create a transaction manager for the master data source
     */
    @Bean(name = "masterTxManager")
    public PlatformTransactionManager masterTxManager(@Qualifier("master") DataSource dataSource) {<!-- -->
        return new DataSourceTransactionManager(dataSource);
    }
    
    @Bean("masterSqlSessionFactory")
    public SqlSessionFactory masterSqlSessionFactory(@Qualifier("master") DataSource dataSource) throws Exception {<!-- -->
        // set the data source
        MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
        mybatisSqlSessionFactoryBean.setDataSource(dataSource);
        // mapper's xml file location
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        String locationPattern = "classpath*:/mapper/master/*.xml";
        mybatisSqlSessionFactoryBean.setMapperLocations(resolver.getResources(locationPattern));
        // corresponding to the entity location of the database
        String typeAliasesPackage = "com.kvn.entity.master";
        mybatisSqlSessionFactoryBean.setTypeAliasesPackage(typeAliasesPackage);
        return mybatisSqlSessionFactoryBean.getObject();
    }
}


-------------------------------------------------- -------------------------------------------------- --------
-------------------------------------------------- -------------------------------------------------- --------


// Slave data source configuration
@Configuration
@MapperScan(basePackages = "com.kvn.mapper.slave", sqlSessionFactoryRef = "masterSqlSessionFactory")
public class SlaveMybatisConfig {<!-- -->

    @Bean("slave")
    @ConfigurationProperties(prefix = "spring.datasource.slave")
    public DataSource slaveDataSource() {<!-- -->
        return DataSourceBuilder.create().build();
    }

    /**
     * Create a transaction manager for the slave data source
     */
    @Bean(name = "slaveTxManager")
    public PlatformTransactionManager slaveTxManager(@Qualifier("slave") DataSource dataSource) {<!-- -->
        return new DataSourceTransactionManager(dataSource);
    }
    
    @Bean("slaveSqlSessionFactory")
    public SqlSessionFactory masterSqlSessionFactory(@Qualifier("slave") DataSource dataSource) throws Exception {<!-- -->
        // set the data source
        MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
        mybatisSqlSessionFactoryBean.setDataSource(dataSource);
        // mapper's xml file location
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        String locationPattern = "classpath*:/mapper/master/*.xml";
        mybatisSqlSessionFactoryBean.setMapperLocations(resolver.getResources(locationPattern));
        // corresponding to the entity location of the database
        String typeAliasesPackage = "com.kvn.entity.slave";
        mybatisSqlSessionFactoryBean.setTypeAliasesPackage(typeAliasesPackage);
        return mybatisSqlSessionFactoryBean.getObject();
    }
}

Summary

Looking at it abstractly, configuring multiple data sources in Spring is actually defining multiple DataSource beans.
To configure the transaction management of multiple data sources is to add TransactionManager transaction management for each DataSource on the basis of multiple DataSource beans device.

Attached:
PlatformTransactionManager is the core interface implemented by Spring transactions. It provides three methods for managing transactions:
1. getTransaction(TransactionDefinition)
2. commit(TransactionStatus)
3. rollback(TransactionStatus)

PlatformTransactionManager provides the ability to manage things, and the interception of @Transactional transaction methods is enabled through @EnableTransactionManagement.
The function of @EnableTransactionManagement is to automatically register BeanFactoryTransactionAttributeSourceAdvisor and let TransactionInterceptor intercept the @Transactional tagged method.

Therefore, under the joint action of PlatformTransactionManager and @EnableTransactionManagement, Spring has the ability to manage things for methods marked with @Transactional.