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方面: