spring boot+Mybatis+automatic+jta实现分布式事务

本文介绍了一种基于Automatic+JTA的分布式事务管理方案,适用于需要操作多个数据源的场景。通过配置Spring Boot相关依赖及属性,实现跨数据源的一致性事务处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

分布式事务解决方案(即操作多个数据源事务解决方案):
有如下几种方案:
automatic+jta ;两段提交协议 ;MQ推送


实现automatic+jta分布式事务管理:
1.添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
<!-- mysql支持 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- mybatis支持 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
2.添加配置到application.properties
spring.jta.enabled=true
#spring.jta.atomikos.properties.service==com.atomikos.icatch.standalone.UserTransactionServiceFactory
#spring.jta.atomikos.properties.max-actives=200
#spring.jta.atomikos.properties.enable-logging=false

spring.datasource.test1.xa-properties.url=jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf-8
spring.datasource.test1.xa-properties.user=root
spring.datasource.test1.xa-properties.password=haosql
spring.datasource.test1.xa-data-source-class-name=com.mysql.jdbc.jdbc2.optional.MysqlXADataSource
spring.datasource.test1.unique-resource-name=test1DataSource //数据源1添加到事务管理中
spring.datasource.test1.max-pool-size=25
spring.datasource.test1.min-pool-size=3
spring.datasource.test1.max-lifetime=20000
spring.datasource.test1.borrow-connection-timeout=10000
spring.datasource.test2.xa-properties.url=jdbc:mysql://localhost:3306/test2?useUnicode=true&characterEncoding=utf-8
spring.datasource.test2.xa-properties.user=root
spring.datasource.test2.xa-properties.password=haosql
spring.datasource.test2.xa-data-source-class-name=com.mysql.jdbc.jdbc2.optional.MysqlXADataSource
spring.datasource.test2.unique-resource-name=test2DataSource //数据源1添加到事务管理中
spring.datasource.test2.max-pool-size=25
spring.datasource.test2.min-pool-size=3
spring.datasource.test2.max-lifetime=20000
spring.datasource.test2.borrow-connection-timeout=10000

3.创建数据源bean
//数据源1
//basePackages="cn.caochong.test1" 使用数据源的包路径
@Configuration
@MapperScan(basePackages="cn.caochong.test1",sqlSessionTemplateRef = "sqlSessionTemplate1")
public class TestMybatisDatasource1 {
@ConfigurationProperties(prefix = "spring.datasource.test1") //自定义配置数据源配置的前缀
@Bean(name="test1DataSource")
@Primary
public DataSource testDataSource() {
return new AtomikosDataSourceBean();
}
@Bean(name="sqlSessionFactory1")
@Autowired
@Primary
public SqlSessionFactory sqlSessionFactory(@Qualifier("test1DataSource") DataSource ds) throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(ds);
return factoryBean.getObject();
}
/**
* 添加事务Bean
* @param ds
* @return
*/
@Primary
@Bean(name="transactionManager1")
@Autowired
public DataSourceTransactionManager transactionManager(@Qualifier("test1DataSource") DataSource ds) {
return new DataSourceTransactionManager(ds);
}
@Primary
@Autowired
@Bean(name="sqlSessionTemplate1")
public SqlSessionTemplate sqlSessionTemplate(@Qualifier("test1DataSource") DataSource ds) throws Exception {
SqlSessionTemplate template = new SqlSessionTemplate(sqlSessionFactory(ds));
return template;
}
}
//数据源2
@Configuration
@MapperScan(basePackages="cn.caochong.test2",sqlSessionTemplateRef = "sqlSessionTemplate2")
public class TestMybatisDatasource2 {
@ConfigurationProperties(prefix = "spring.datasource.test2") //自定义配置数据源配置的前缀
@Bean(name="test2DataSource")
public DataSource testDataSource() {
return new AtomikosDataSourceBean();
}
@Bean(name="sqlSessionFactory2")
@Autowired
public SqlSessionFactory sqlSessionFactory(@Qualifier("test2DataSource") DataSource ds) throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(ds);
return factoryBean.getObject();
}
/**
* 添加事务Bean
* @param ds
* @return
*/
@Bean(name="transactionManager2")
@Autowired
public DataSourceTransactionManager transactionManager(@Qualifier("test2DataSource") DataSource ds) {
return new DataSourceTransactionManager(ds);
}
@Autowired
@Bean(name="sqlSessionTemplate2")
public SqlSessionTemplate sqlSessionTemplate(@Qualifier("test2DataSource") DataSource ds) throws Exception {
SqlSessionTemplate template = new SqlSessionTemplate(sqlSessionFactory(ds));
return template;
}
}

4.创建事务管理器
public class TransactionManagerConfig {
/**
* 自定义事务
* MyBatis自动参与到spring事务管理中,无需额外配置,
* 只要org.mybatis.spring.SqlSessionFactoryBean
* 引用的数据源与DataSourceTransactionManager引用的数据源一致即可,否则事务管理会不起作用。
*/
@Bean(name = "userTransaction")
public UserTransaction userTransaction() throws Throwable {
UserTransactionImp userTransactionImp = new UserTransactionImp();
userTransactionImp.setTransactionTimeout(10000);
return userTransactionImp;
}
@Bean(name = "atomikosTransactionManager", initMethod = "init", destroyMethod = "close")
public TransactionManager atomikosTransactionManager() throws Throwable {
UserTransactionManager userTransactionManager = new UserTransactionManager();
userTransactionManager.setForceShutdown(false);
return userTransactionManager;
}
@Bean(name = "transactionManager")
@DependsOn({ "userTransaction", "atomikosTransactionManager" })
public PlatformTransactionManager transactionManager() throws Throwable {
UserTransaction userTransaction = userTransaction();
JtaTransactionManager manager = new JtaTransactionManager(userTransaction, atomikosTransactionManager());
return manager;
}
}

5.添加service进行事务控制业务
@Service
public class UserServiceTran {
@Autowired
private UserMapper1 userMapper1;
@Autowired
private UserMapper2 userMapper2;
@Transactional(value="transactionManager")
public void addUser() {
userMapper2.add(34, "manysourcenew3");
int i=1/0;
userMapper1.add(34, "manysourcenew3");
}
}

6.创建controller进行访问测试(UserService1和UserService2普通service业务,自己去实现)
@RestController
public class UserController {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private UserService1 userServiceImpl1;
@Autowired
private UserService2 userServiceImpl2;
@Autowired
UserServiceTran userServiceTran;

@RequestMapping("/add")
public String add() {
userServiceTran.addUser();
return "success";
}
@RequestMapping("/find1")
public List<User> find() {
logger.info("find1 user");
return userServiceImpl1.find();
}
@RequestMapping("/find2")
public List<User> find2() {
return userServiceImpl2.find();
}
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值