这种方式只适用于
对于真正分布式应用不适用,原因在于 Atomikos需要获得所有数据源 统一进行事务管理
JTA(Java Transaction API)被称为Java事务API,是由Java语言提供的一套解决分布式事务的API标准
XA协议
1 2 3 | 1. XA协议是JTA的基础 2. XA协议最早由Tuxedo首先提出,并交给X/Open组织,作为资源管理器(数据库)与事务管理器的接口标准 3. XA协议采用两阶段提交方式来管理分布式事务,MySQL从5.x版本开始支XA协议 |
Atomikos事务管理器
3.1 Atomikos简介
1 2 | Atomikos是一款Java/JTA事务处理工具,在SpringBoot的官网文档的分布式事务处理中Atomikos作为一种分布式事务的解决方案. 文档地址: https://docs.spring.io/spring-boot/docs/2.1.18.RELEASE/reference/html/boot-features-jta.html |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 从SpringBoot的官网可以看出,官网介绍非常简单,说了要想使用需要添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jta-atomikos</artifactId> </dependency> 然后就没介绍一些更多细节,不过Atomikos相对来说比较简单,只需要一个核心API即可 核心API介绍 1. AtomikosDataSourceBean 1.1 这个类是Atomikos连接池的首选类 1.2 如果要开启Atomikos JTA首选就是实例化此类 1.3 接下来要做的就是实例化此类的对象,并设置对象的属性 1.4 创建好此类对象后它会自动的加入到事务管理中 1.5 所有通过此类获取的连接执行的SQL都会加入到JTA事务管理 |
Configuration
@MapperScan(basePackages = {"com.example.demo.mapper"},sqlSessionFactoryRef = "primarySqlSessionFactory")
public class DataSourceConfig1 {
@Value("${spring.datasource.primary.url}")
private String url;
@Value("${spring.datasource.primary.username}")
private String username;
@Value("${spring.datasource.primary.password}")
private String password;
@Value("${spring.datasource.primary.driver-class-name}")
private String driverClassName;
@Primary
@Bean(name="primaryDataSource")
public DataSource primaryDataSource(){
//return DataSourceBuilder.create().build();
//将事务统一交给Atomikos处理 不要自己定义事务管理器
AtomikosDataSourceBean ds = new AtomikosDataSourceBean();
DruidXADataSource dds = new DruidXADataSource();
dds.setUsername(username);
dds.setPassword(password);
dds.setUrl(url);
dds.setDriverClassName(driverClassName);
ds.setXaDataSource(dds);
ds.setUniqueResourceName("primaryDataSource");
return ds;
}
@Primary
@Bean(name="primarySqlSessionFactory")
public SqlSessionFactory primarySqlSessionFactory(@Qualifier("primaryDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean=new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setTypeAliasesPackage("com.example.demo.pojo");
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mappers/*Mapper.xml"));
SqlSessionFactory sqlSessionFactory = bean.getObject();
sqlSessionFactory.getConfiguration().setMapUnderscoreToCamelCase(true);
//sqlSessionFactory.getConfiguration().setJdbcTypeForNull(JdbcType.NULL);
return sqlSessionFactory;
}
@Primary
@Bean(name="primarySqlSessionTemplate")
public SqlSessionTemplate primarySqlSessionTemplate(@Qualifier("primarySqlSessionFactory")SqlSessionFactory sqlSessionFactory){
return new SqlSessionTemplate(sqlSessionFactory);
}
@Primary
@Bean(name="primaryJdbcTemplate")
public JdbcTemplate primaryJdbcTemplate(@Qualifier("primaryDataSource")DataSource dataSource){
return new JdbcTemplate(dataSource);
}
// @Bean(name="primaryTransactionManager")
// public DataSourceTransactionManager primaryTransactionManager(@Qualifier("primaryDataSource")DataSource dataSource){
// return new DataSourceTransactionManager(dataSource);
// }
}
@Configuration
@MapperScan(basePackages = {"com.example.demo.mapper2"},sqlSessionFactoryRef = "secondSqlSessionFactory")
public class DataSourceConfig2 {
@Value("${spring.datasource.second.url}")
private String url;
@Value("${spring.datasource.second.username}")
private String username;
@Value("${spring.datasource.second.password}")
private String password;
@Value("${spring.datasource.second.driver-class-name}")
private String driverClassName;
@Bean(name="secondDataSource")
//@ConfigurationProperties(prefix = "spring.datasource.second")
public DataSource secondDataSource(){
//return DataSourceBuilder.create().build();
AtomikosDataSourceBean ds = new AtomikosDataSourceBean();
DruidXADataSource dds = new DruidXADataSource();
dds.setUsername(username);
dds.setPassword(password);
dds.setUrl(url);
dds.setDriverClassName(driverClassName);
ds.setXaDataSource(dds);
ds.setUniqueResourceName("secondDataSource");
return ds;
}
@Bean(name="secondSqlSessionFactory")
public SqlSessionFactory secondSqlSessionFactory(@Qualifier("secondDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean=new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setTypeAliasesPackage("com.example.demo.pojo2");
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mappers2/*Mapper.xml"));
SqlSessionFactory sqlSessionFactory = bean.getObject();
sqlSessionFactory.getConfiguration().setMapUnderscoreToCamelCase(true);
//sqlSessionFactory.getConfiguration().setJdbcTypeForNull(JdbcType.NULL);
return sqlSessionFactory;
}
@Bean(name="secondSqlSessionTemplate")
public SqlSessionTemplate secondSqlSessionTemplate(@Qualifier("secondSqlSessionFactory")SqlSessionFactory sqlSessionFactory){
return new SqlSessionTemplate(sqlSessionFactory);
}
@Bean(name="secondJdbcTemplate")
public JdbcTemplate secondJdbcTemplate(@Qualifier("secondDataSource")DataSource dataSource){
return new JdbcTemplate(dataSource);
}
// @Bean(name="secondTransactionManager")
// public DataSourceTransactionManager secondTransactionManager(@Qualifier("secondDataSource")DataSource dataSource){
// return new DataSourceTransactionManager(dataSource);
// }
}
上面用的druid连接池
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jta-atomikos</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.2.15</version> </dependency> <dependency>
使用时候
@Transactional 不要指定事务管理器 也不要自定义事务管理器
测试中 连接阿里云RDS服务器一直有问题