springbootdruidmybatismysql多数据源事务管理
时间:2019-10-06
本文章向大家介绍springbootdruidmybatismysql多数据源事务管理,主要包括springbootdruidmybatismysql多数据源事务管理使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
springboot+druid+mybatis+mysql+多数据源事务管理
分布式事务在java中的解决方案就是JTA(即Java Transaction API);springboot官方提供了 Atomikos or Bitronix的解决思路;其实,大多数情况下很多公司是使用消息队列的方式实现分布式事务。这里分享的是Atomikos 的简单事务管理。
项目依赖
pom.xml中添加atomikos的springboot相关依赖:
<!--分布式事务管理器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<!--这里最好要5.1.47之后的版本-->
<version>5.1.47</version>
</dependency>
application.properties配置文件中数据库相关信息:
#数据库1
spring.datasource.druid.one.url=jdbc:mysql://localhost:3306/test01?useUnicode=true&characterEncoding=utf-8
spring.datasource.druid.one.username=root
spring.datasource.druid.one.password=123456
#数据库2
spring.datasource.druid.two.url=jdbc:mysql://localhost:3306/test02?useUnicode=true&characterEncoding=utf-8
spring.datasource.druid.two.username=root
spring.datasource.druid.two.password=123456
创建两个java配置类,分别读取上面的两个数据库相关信息:
@ConfigurationProperties(prefix = "spring.datasource.druid.one")
public class DsOneProperties {
private String username;
private String password;
private String url;
//这里省掉Set和get方法
}
@ConfigurationProperties(prefix = "spring.datasource.druid.two")
public class DsTwoProperties {
private String username;
private String password;
private String url;
//这里省掉Set和get方法
}
在SpringBoot项目启动类加上注解,启动时,就加载相关信息
@EnableConfigurationProperties(value = {DsOneProperties.class, DsTwoProperties.class})
创建主数据库配置类MyBatisConfigOne :
@Configuration//声明该类是一个配置类
@MapperScan(basePackages = "com.lwh.mybatistest.mapper", sqlSessionFactoryRef = "sqlSessionFactory1", sqlSessionTemplateRef = "sqlSessionTemplate1")
//扫描的包是com.lwh.mybatistest.mapper
public class MyBatisConfigOne {
// 配置主数据源
@Primary
@Bean
public DataSource dsOne(DsOneProperties dsOneProperties) throws SQLException {
//配置XA协议数据源,从配置文件中读取相应属性
MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();
mysqlXaDataSource.setUrl(dsOneProperties.getUrl());
mysqlXaDataSource.setPassword(dsOneProperties.getPassword());
mysqlXaDataSource.setUser(dsOneProperties.getUsername());
//将本地事务注册到Atomikos全局事务
AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
xaDataSource.setXaDataSource(mysqlXaDataSource);
xaDataSource.setUniqueResourceName("dsOne");
return xaDataSource;
}
@Primary
@Bean(name = "sqlSessionFactory1")
public SqlSessionFactory SqlSessionFactory1(@Qualifier("dsOne") DataSource dataSource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
return bean.getObject();
}
@Primary
@Bean(name = "sqlSessionTemplate1")
public SqlSessionTemplate SqlSessionTemplate1(
@Qualifier("sqlSessionFactory1") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
依照上面主数据库配置类,创建从数据库配置类:
@Configuration
@MapperScan(basePackages = "com.lwh.mybatistest.mapper2", sqlSessionFactoryRef = "sqlSessionFactory2", sqlSessionTemplateRef = "sqlSessionTemplate2")
public class MyBatisConfigTwo {
@Bean
public DataSource dsTwo(DsTwoProperties dsTwoProperties) throws SQLException {
//配置从数据源
//配置XA协议数据源,从配置文件中读取相应属性
MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();
mysqlXaDataSource.setUrl(dsTwoProperties.getUrl());
mysqlXaDataSource.setPassword(dsTwoProperties.getPassword());
mysqlXaDataSource.setUser(dsTwoProperties.getUsername());
//将本地事务注册到Atomikos全局事务
AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
xaDataSource.setXaDataSource(mysqlXaDataSource);
xaDataSource.setUniqueResourceName("dsTwo");
return xaDataSource;
}
@Bean(name = "sqlSessionFactory2")
public SqlSessionFactory SqlSessionFactory2(@Qualifier("dsTwo") DataSource dataSource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
return bean.getObject();
}
@Bean(name = "sqlSessionTemplate2")
public SqlSessionTemplate SqlSessionTemplate2(
@Qualifier("sqlSessionFactory2") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
创建一个简单的controller测试类:
@RestController
@RequestMapping("/book")
public class BookController {
@Autowired
BookService bookService;
@Autowired
BookService2 bookService2;
@GetMapping("/add1")
@Transactional
public String addBook() {
Book book = new Book();
book.setBookname("测试");
book.setAuthor("test:01");
System.out.println("数据库1:>>>>");
bookService.addBook(book);
System.out.println("数据库2:>>>>");
bookService2.addBook(book);
return "测试add1操作成功!";
}
@GetMapping("/add2")
@Transactional
public String addBook2() {
Book book = new Book();
book.setBookname("测试add2");
book.setAuthor("test:01");
System.out.println("数据库1:>>>>");
bookService.addBook(book);
int a = 10 / 0;
System.out.println("数据库2:>>>>");
bookService2.addBook(book);
return "测试add2操作成功!";
}
}
Service类,就是简单的插入方法,调用mapper:
@Service
public class BookService {
@Autowired
BookMapper bookMapper;
public void addBook(Book book) {
bookMapper.insertSelective(book);
}
}
springboot默认有事务管理器,所以这里没有配置,使用默认的即可,如果有特别需求,可以自行创建自己的事务管理器。
最简单的atomikos插件的使用就配置完了,配置信息相对简单,想深入学习的同学,可以参考官方的文档。
分布式事务有多种主流形态,包括:
基于消息实现的分布式事务
基于补偿实现的分布式事务(gts/seata自动补偿的形式)
基于TCC实现的分布式事务
基于SAGA实现的分布式事务
基于2PC实现的分布式事务
之所以有这么多形态,是因为任何事情都没有银弹,只有最合适当前场景的解决方案。
原文地址:https://www.cnblogs.com/LoveShare/p/11627460.html
- 3339: Rmq Problem
- Codeforce GYM 100741 A. Queries
- UVA - 11178 Morley's Theorem
- PyMySQL模块的使用
- Python之进程
- Angularjs 通过asp.net web api认证登录
- P3391 【模板】文艺平衡树(Splay)
- 零基础入门小程序 &实战经验分享
- mysql explain详解
- 【前沿】Pytorch开源VQA神经网络模块,让你快速完成看图问答
- #106. 二逼平衡树(附带详细代码注释)
- TensorFlow.js、迁移学习与AI产品创新之道
- Java JDBC MySQL
- python内置函数大全
- MySQL 教程
- MySQL 安装
- MySQL 管理与配置
- MySQL PHP 语法
- MySQL 连接
- MySQL 创建数据库
- MySQL 删除数据库
- MySQL 选择数据库
- MySQL 数据类型
- MySQL 创建数据表
- MySQL 删除数据表
- MySQL 插入数据
- MySQL 查询数据
- MySQL where 子句
- MySQL UPDATE 查询
- MySQL DELETE 语句
- MySQL LIKE 子句
- mysql order by
- Mysql Join的使用
- MySQL NULL 值处理
- MySQL 正则表达式
- MySQL 事务
- MySQL ALTER命令
- MySQL 索引
- MySQL 临时表
- MySQL 复制表
- 查看MySQL 元数据
- MySQL 序列 AUTO_INCREMENT
- MySQL 处理重复数据
- MySQL 及 SQL 注入
- MySQL 导出数据
- MySQL 导入数据
- MYSQL 函数大全
- MySQL Group By 实例讲解
- MySQL Max()函数实例讲解
- mysql count函数实例
- MYSQL UNION和UNION ALL实例
- MySQL IN 用法
- MySQL between and 实例讲解
- 科学与艺术的融合:遗传算法绘制蒙娜丽莎
- “工业听诊”中多声源事件检测与定位
- 工业党福利:使用PaddleX高效实现指针型表计读取系列文章(2)
- 【三维点云系列】PCL点云库之数据文件与IO操作
- Jvm故障处理工具
- 递增子序列
- redis学习(二)
- You-Get 使用方法
- 接口测试 Mock 实战 | 结合 jq 完成批量化的手工 Mock
- 在Angular应用的child Component里同时使用@Input和@Output
- Angular应用里的@Input和@Output注解使用方法介绍
- K8S Ingress使用|常见问题列表
- 部署Tomcat及负载均衡
- Jenkins常用插件Publish Over SSH
- Zabbix 4.0配置监控Linux客户端