SpringBoot+JTA+Mybatis
2024-09-05 04:09:26
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。
在实际开发中,我们一个项目可能会用到多个数据库,通常一个数据库对应一个数据源。这时候就要管理多数据源事务。
什么是jta:https://www.ibm.com/developerworks/cn/java/j-lo-jta/
pom.xml
注意这里的druid用1.1.9
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter</artifactId>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-web</artifactId>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-test</artifactId>
-
<scope>test</scope>
-
</dependency>
-
<dependency>
-
<groupId>org.mybatis.spring.boot</groupId>
-
<artifactId>mybatis-spring-boot-starter</artifactId>
-
<version>1.1.1</version>
-
</dependency>
-
<dependency>
-
<groupId>mysql</groupId>
-
<artifactId>mysql-connector-java</artifactId>
-
</dependency>
-
<dependency>
-
<groupId>com.alibaba</groupId>
-
<artifactId>druid</artifactId>
-
<version>1.1.9</version>
-
</dependency>
-
<!-- JPA -->
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-data-jpa</artifactId>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
-
</dependency>
配置第一个数据源
-
import com.alibaba.druid.pool.xa.DruidXADataSource;
-
import com.atomikos.icatch.jta.UserTransactionImp;
-
import com.atomikos.icatch.jta.UserTransactionManager;
-
import org.apache.ibatis.session.SqlSessionFactory;
-
import org.mybatis.spring.SqlSessionFactoryBean;
-
import org.mybatis.spring.annotation.MapperScan;
-
import org.springframework.beans.factory.annotation.Qualifier;
-
import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
-
import org.springframework.context.annotation.Bean;
-
import org.springframework.context.annotation.Configuration;
-
import org.springframework.context.annotation.Primary;
-
import org.springframework.transaction.jta.JtaTransactionManager;
-
import javax.sql.DataSource;
-
import javax.transaction.UserTransaction;
-
-
-
@Configuration
-
// // 扫描 Mapper 接口并容器管理
-
@MapperScan(value ="mapper所在包路径" ,sqlSessionFactoryRef = "moviesSqlSessionFactory")
-
public class MoviesDataSourceConfig {
-
-
-
@Bean(name = "moviesDataSource")
-
@Primary
-
public DataSource masterDataSource() {
-
DruidXADataSource druidXADataSource = new DruidXADataSource();
-
druidXADataSource.setUrl("jdbc:mysql://localhost:3306/movies?useUnicode=true&characterEncoding=UTF8&useSSL=false");
-
druidXADataSource.setUsername("root");
-
druidXADataSource.setPassword("");
-
-
AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
-
atomikosDataSourceBean.setXaDataSource(druidXADataSource);
-
atomikosDataSourceBean.setUniqueResourceName("moviesDataSource");
-
atomikosDataSourceBean.setPoolSize(5);
-
-
return atomikosDataSourceBean;
-
}
-
-
/*
-
* 使用这个来做总事务 后面的数据源就不用设置事务了
-
* */
-
@Bean(name = "transactionManager")
-
@Primary
-
public JtaTransactionManager regTransactionManager () {
-
UserTransactionManager userTransactionManager = new UserTransactionManager();
-
UserTransaction userTransaction = new UserTransactionImp();
-
return new JtaTransactionManager(userTransaction, userTransactionManager);
-
}
-
-
@Bean(name = "moviesSqlSessionFactory")
-
@Primary
-
public SqlSessionFactory masterSqlSessionFactory(@Qualifier("moviesDataSource") DataSource masterDataSource)
-
throws Exception {
-
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
-
sessionFactory.setDataSource(masterDataSource);
-
return sessionFactory.getObject();
-
}
-
-
-
-
}
注意:不管有多少个数据源只要配置一个 JtaTransactionManager。
还有 DataSource里用的是DruidXADataSource ,而后注册到AtomikosDataSourceBean并且返回。
配置第二个数据源
-
import com.alibaba.druid.pool.xa.DruidXADataSource;
-
-
import org.apache.ibatis.session.SqlSessionFactory;
-
import org.mybatis.spring.SqlSessionFactoryBean;
-
import org.mybatis.spring.annotation.MapperScan;
-
import org.springframework.beans.factory.annotation.Qualifier;
-
import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
-
import org.springframework.context.annotation.Bean;
-
import org.springframework.context.annotation.Configuration;
-
-
import javax.sql.DataSource;
-
-
@Configuration
-
// // 扫描 Mapper接口
-
@MapperScan(value ="com.sunsharing.mapper" ,sqlSessionFactoryRef = "teacherSqlSessionFactory")
-
public class TeacherDataSourceConfig {
-
-
-
@Bean(name = "teacherDataSource")
-
public DataSource masterDataSource() {
-
DruidXADataSource druidXADataSource = new DruidXADataSource();
-
druidXADataSource.setUrl("jdbc:mysql://localhost:3306/reactstu?useUnicode=true&characterEncoding=UTF8&useSSL=false");
-
druidXADataSource.setUsername("root");
-
druidXADataSource.setPassword("");
-
-
AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
-
atomikosDataSourceBean.setXaDataSource(druidXADataSource);
-
atomikosDataSourceBean.setUniqueResourceName("teacherDataSource");
-
atomikosDataSourceBean.setPoolSize(5);
-
return atomikosDataSourceBean;
-
}
-
-
-
@Bean(name = "teacherSqlSessionFactory")
-
public SqlSessionFactory masterSqlSessionFactory(@Qualifier("teacherDataSource") DataSource masterDataSource)
-
throws Exception {
-
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
-
sessionFactory.setDataSource(masterDataSource);
-
return sessionFactory.getObject();
-
}
-
-
}
这里就不用配置JtaTransactionManager了。
测试:
-
@Autowired
-
MoviesMapper moviesMapper;
-
-
@Autowired
-
TeacherMapper teacherMapper;
-
-
-
@RequestMapping(method = RequestMethod.GET)
-
public MyResponseJson twodata() {
-
for (int i = 0;i < 5;i++) {
-
if(i < 2) {
-
Teacher teacher = new Teacher("3", 10);
-
teacherMapper.insertteacher(teacher);
-
Movies movies = new Movies("3", "3", 50, 10);
-
moviesMapper.insertmovies(movies);
-
-
}else {
-
throw new RuntimeException();
-
}
-
}
-
return new MyResponseJson(200, "成功!", null);
-
}
测试结果:可以回滚
最新文章
- 易企秀微场景2016最新完整版V10.5,小编亲测修复众多错误
- FFT 快速傅里叶变换浅析
- 「LeetCode」全部题解
- 线程同步之 yield() wait()
- 【C#】第3章学习要点(二)自定义类和结构
- Aix下如何运行Java程序
- 【Android测试】【第十七节】Instrumentation——App任你摆布(反射技术的引入)
- scanf()读取带空格的字符串
- scp 指定端口
- Android App组件之ListFragment -- 说明和示例
- LA 2965 Jurassic Remains (中途相遇法)
- js函数语法
- iOS Dev (21) 用 AVPlayer 播放一个本地音频文件
- linux 使用ssh到远端并且使用while的坑
- make工具与Makefile文件
- C语言库函数大全及应用实例十
- 在学java继承中
- io多路复用(一)
- Android values资源的定义
- 设计模式总结篇系列:适配器模式(Adapter)