第10篇:多库事务
描述
Spring 的声明式事务方法@Transactional只支持单数据源。
分布式事务方案选择:
- 2PC(两阶段提交)
- 3PC(三阶段提交)
- TCC(补偿机制)
- 最大努力通知
- XA
- 本地消息表(eBay)
- 事务消息/最终一致性(RocketMQ)
然后,JTA即Java Transaction API和JTS即Java Transaction Service为Java EE提供了分布式事务服务,包括事务管理器 TM、资源管理器 RM(支持XA协议,如JMS、JDBC数据库连接池等)。
弊端:两阶段提交等
参考:
https://www.zhihu.com/question/64921387
https://juejin.im/post/6844903666273484814
流程
- 依赖
- 数据源配置
- 定义配置bean
- 配置Atomikos
- 使用
1. 依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>
2. 数据源配置及JTA配置
spring.jta.transaction-manager-id=txManager
spring.jta.atomikos.properties.log-base-dir=log/tm/
# 数据源配置略:test1、test2
3. 定义配置bean
@Data
public class DSConfig {
private String jdbcUrl;
private String username;
private String password;
private String driverClassName;
}
4. 配置Atomikos
@Configuration
@MapperScan(basePackages = {"com.example.demo.mapper.test1"},
sqlSessionTemplateRef = "test1SqlSessionTemplate")
public class DataSource1Config {
@Bean("test1")
@ConfigurationProperties(prefix = "spring.datasource.test1")
public DSConfig test1() {
return new DSConfig();
}
@Bean(name = "test1Ds")
@Primary
public DataSource dataSource(@Qualifier("test1") DSConfig dsConfig) throws SQLException {
MysqlXADataSource mysqlXADataSource = new MysqlXADataSource();
mysqlXADataSource.setUrl(dsConfig.getJdbcUrl());
mysqlXADataSource.setUser(dsConfig.getUsername());
mysqlXADataSource.setPassword(dsConfig.getPassword());
mysqlXADataSource.setPinGlobalTxToPhysicalConnection(true);
// 交给事务管理器进行管理
AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
atomikosDataSourceBean.setBeanName("test1Ds");
atomikosDataSourceBean.setXaDataSource(mysqlXADataSource);
return atomikosDataSourceBean;
}
@Bean("test1SqlSessionFactory")
@Primary
public SqlSessionFactory test1SqlSessionFactory(@Qualifier("test1Ds") DataSource dataSource)
throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/test1/*.xml"));
return factoryBean.getObject();
}
@Bean("test1SqlSessionTemplate")
@Primary
public SqlSessionTemplate test1SqlSessionTemplate(@Qualifier("test1SqlSessionFactory") SqlSessionFactory factory) {
return new SqlSessionTemplate(factory);
}
}
5. 使用
@Transactional