springboot中使用jta+atomikos处理多数据源分布式事务问题
多数据源拆分思路:
例子:公司分为两个数据库,一个数据库专门存放共同配置文件,一个数据库是垂直业务数据库
垂直: 业务划分具体数据库
在一个项目中可以有无限个数据源,具体多少根据内存大小
在一个项目多数据源如何划分:
(1)分包名: (常用)
com.lqr.test01 — datasource1
com.lqr.test02 — datasource2
类似多个不同jar包,对应不同业务需求。
多个不同的业务需求,存放在同一个项目中。
(2)注解方式:
使用AOP拦截,自定义一个注解
spring事务管理:
(1)spring事务分类:
声明事务
编程事务
(2)spring事务原理:
AOP技术环绕通知进行拦截
使用spring事务注意事项:不要try,原因:要把异常抛出给外层
(3)@Transactional注解:
使用@Transactional注解后可以解决多条SQL语句中上一条SQL添加语句成功而第二条SQL添加语句失败导致的不满足一致性的问题,可以在任一一条SQL语句异常时整个方法回滚。
在处理多数据源的时候,需要对每个数据源(DataSource)配置对应的事务管理器(transactionManager),并在需要进行事务管理的方法上加上@Transactional注解并设置事务管理器,如:
就可以使该数据源的SQL语句回滚。
但是存在一个问题,如果项目中的某个方法同时对两个数据源的表进行了SQL添加/删除/更新语句操作,那么只指定一个事务管理器的话,发生异常将只有该事务管理器对应的数据源的SQL操作回滚,而另一个数据源的SQL操作则不会回滚,违反了一致性的原则。
这里介绍如何使用jta+atomikos来解决多数据源分布式事务问题:
步骤如下:
(1)在pom.xml文件中添加依赖:
<dependencies>
<!-- jta+atomikos -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>
<!--freemarker -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!-- AOP -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- log4j -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
<version>1.3.8.RELEASE</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot