Springboot+atmikos多數據源事務一致性

1、pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>
<dependency>
	<groupId>javax.transaction</groupId>
	<artifactId>jta</artifactId>
	<version>1.1</version>
</dependency>
<dependency>
	<groupId>com.atomikos</groupId>
	<artifactId>atomikos-util</artifactId>
	<version>4.0.2</version>
</dependency>
<dependency>
	<groupId>com.atomikos</groupId>
	<artifactId>transactions</artifactId>
	<version>4.0.2</version>
</dependency>
<dependency>
	<groupId>com.atomikos</groupId>
	<artifactId>transactions-api</artifactId>
	<version>4.0.2</version>
</dependency>

2、JtaTransationConfig

@Configuration 
@EnableTransactionManagement  
@EnableAspectJAutoProxy(exposeProxy = true)
public class JtaTransationConfig { 

    @Bean(name = "userTransaction")
    public UserTransaction userTransaction() throws Throwable {
        UserTransactionImp userTransactionImp = new UserTransactionImp();
        userTransactionImp.setTransactionTimeout(30000);
        return userTransactionImp;
    }

    @Bean(name = "atomikosTransactionManager", initMethod = "init", destroyMethod = "close")
    public TransactionManager atomikosTransactionManager() {
        UserTransactionManager userTransactionManager = new UserTransactionManager();
        userTransactionManager.setForceShutdown(true);
        return userTransactionManager;
    }

    @Bean(name = "transactionManager")
    @DependsOn({ "userTransaction", "atomikosTransactionManager" })
    public PlatformTransactionManager transactionManager() throws Throwable {
        UserTransaction userTransaction = userTransaction();
        TransactionManager atomikosTransactionManager = atomikosTransactionManager();
        return new JtaTransactionManager(userTransaction, atomikosTransactionManager);
    }
}

3、JtaDatasourceConfig

@Configuration 
public class JtaDatasourceConfig { 

	@Bean("one") 
	@Primary
	@DependsOn({ "transactionManager"})
    public DataSource createXADatasourOne(Environment env) { 

		MysqlXADataSource druidXADataSource = new MysqlXADataSource(); 
        druidXADataSource.setUrl(env.getProperty("spring.datasource.druid.master.url")); 
        druidXADataSource.setUser(env.getProperty("spring.datasource.druid.master.username")); 
        druidXADataSource.setPassword(env.getProperty("spring.datasource.druid.master.password"));

        AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean(); 
        atomikosDataSourceBean.setXaDataSourceClassName("com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"); 
        atomikosDataSourceBean.setUniqueResourceName("one1"); 
        atomikosDataSourceBean.setXaDataSource(druidXADataSource); 
        atomikosDataSourceBean.setMaintenanceInterval(30000); 
        atomikosDataSourceBean.setTestQuery("SELECT 1"); 
        atomikosDataSourceBean.setMinPoolSize(5);
        atomikosDataSourceBean.setMaxPoolSize(20);
        atomikosDataSourceBean.setMaxIdleTime(60);

        return atomikosDataSourceBean; 
    } 

    @Bean("two") 
    @DependsOn({ "transactionManager"})
    public DataSource createXADatasourTwo(Environment env) { 
    	
    	MysqlXADataSource druidXADataSource = new MysqlXADataSource(); 
        druidXADataSource.setUrl(env.getProperty("spring.datasource.druid.slave.url")); 
        druidXADataSource.setUser(env.getProperty("spring.datasource.druid.slave.username")); 
        druidXADataSource.setPassword(env.getProperty("spring.datasource.druid.slave.password"));

        AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean(); 
        atomikosDataSourceBean.setXaDataSourceClassName("com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"); 
        atomikosDataSourceBean.setUniqueResourceName("two2"); 
        atomikosDataSourceBean.setXaDataSource(druidXADataSource);
        atomikosDataSourceBean.setMaintenanceInterval(30000); 
        atomikosDataSourceBean.setTestQuery("SELECT 1"); 
        atomikosDataSourceBean.setMinPoolSize(5);
        atomikosDataSourceBean.setMaxPoolSize(20);
        atomikosDataSourceBean.setMaxIdleTime(60);

        return atomikosDataSourceBean; 
    } 

}

4、MyBatisConfig

@Configuration
@MapperScan(basePackages = {"com.test.**.mapper"}, sqlSessionTemplateRef = "sqlSessionTemplate") 
public class MyBatisConfig
{
	@Autowired
    private Environment env;
    
	@Bean("xaSqlSessionFactoryOne")
	@Primary
    public SqlSessionFactory xaSqlSessionFactoryOne(@Qualifier("one")DataSource one) { 

        try { 
            return createSqlSessionFactory(one);
        } catch (Exception e) { 
            e.printStackTrace(); 
            return null; 
        } 
    } 

    @Bean("xaSqlSessionFactoryTwo")
    public SqlSessionFactory xaSqlSessionFactoryTwo(@Qualifier("two")DataSource two) { 

        try { 
            return createSqlSessionFactory(two);
        } catch (Exception e) { 
            e.printStackTrace(); 
            return null; 
        } 
    }

    private SqlSessionFactory createSqlSessionFactory(DataSource dataSource) throws Exception{ 

    	String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage");
        String mapperLocations = env.getProperty("mybatis.mapperLocations");
        String configLocation = env.getProperty("mybatis.configLocation");
        typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage);
        VFS.addImplClass(SpringBootVFS.class);
        
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); 
        sqlSessionFactoryBean.setDataSource(dataSource); 
        sqlSessionFactoryBean.setTypeAliasesPackage(typeAliasesPackage);
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocations));
        sqlSessionFactoryBean.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));

        return sqlSessionFactoryBean.getObject(); 
    } 
    
	@Bean("sqlSessionTemplate") 
    public CustomSqlSessionTemplate sqlSessionTemplate(@Qualifier("xaSqlSessionFactoryOne")SqlSessionFactory xaSqlSessionFactoryOne, @Qualifier("xaSqlSessionFactoryTwo")SqlSessionFactory xaSqlSessionFactoryTwo) { 

        Map<Object, SqlSessionFactory> targetSqlSessionFactorys = new HashMap<>(); 
        targetSqlSessionFactorys.put(DataSourceType.MASTER, xaSqlSessionFactoryOne); 
        targetSqlSessionFactorys.put(DataSourceType.SLAVE, xaSqlSessionFactoryTwo); 

        CustomSqlSessionTemplate customSqlSessionTemplate = new CustomSqlSessionTemplate(xaSqlSessionFactoryOne); 
        customSqlSessionTemplate.setTargetSqlSessionFactorys(targetSqlSessionFactorys); 

        return customSqlSessionTemplate; 
    } 
    
}

5、創建一個類CustomSqlSessionTemplate繼承org.mybatis.spring.SqlSessionTemplate

並重寫getSqlSessionFactory()方法

6、DataSourceAspect、DynamicDataSourceContextHolder等

參考:https://blog.csdn.net/qazxsw635241/article/details/102793457

7、service方面:

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章