第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