springboot2.0 解决多数据源分布式事务问题
2021-03-04 10:28
标签:lombok == pom ppi unit web atomikos 一个数据库 mapper 大家都知道,在多数据源的项目中可能会发生的事务问题,因为一个库的事务不可能去操作另一个数据库的事务嘛,这里使用传统的分布式事务解决方案:SpringBoot+JTA+Atomikos 使用atomikos对数据库的事务进行统一的管理,但是这套解决方案不适合微服务,需要拿到数据源然后注册到同一个全局事务里面去 好,那我们如何配置呢?话不多说直接上代码 pom.xml配置 application.properties配置 MemberConfig以及OrderConfig的配置bean 会员数据源MemberDataSourceConfig配置 订单数据源OrderDataSourceConfig配置 controller层 service实现 mapper层 项目启动类 最后附上项目结构目录,如图 ok,直接启动运行即可 springboot2.0 解决多数据源分布式事务问题 标签:lombok == pom ppi unit web atomikos 一个数据库 mapper 原文地址:https://www.cnblogs.com/w-wu/p/14303119.html 1 2
1 server.port=8090
2 server.servlet.context-path=/
3 #单数据源
4 #spring.datasource.driverClassName=com.mysql.jdbc.Driver
5 #spring.datasource.url=jdbc:mysql://localhost:3306/cboot?useUnicode=true&characterEncoding=UTF-8
6 #spring.datasource.username=root
7 #spring.datasource.password=root
8
9 #多数据源-订单
10 spring.datasource.order.driverClassName=com.mysql.jdbc.Driver
11 spring.datasource.order.url=jdbc:mysql://localhost:3306/cboot?useUnicode=true&characterEncoding=UTF-8
12 spring.datasource.order.username=root
13 spring.datasource.order.password=root
14
15 #多数据源-会员
16 spring.datasource.member.driverClassName=com.mysql.jdbc.Driver
17 spring.datasource.member.url=jdbc:mysql://localhost:3306/cboot1?useUnicode=true&characterEncoding=UTF-8
18 spring.datasource.member.username=root
19 spring.datasource.member.password=root
1 package com.wuwu.cboot.config;
2
3 import lombok.Data;
4 import org.springframework.boot.context.properties.ConfigurationProperties;
5
6 /**
7 * @Description:会员数据库连接属性
8 * @author: wph
9 * @Version: 1.0
10 * @date: 2021/1/15
11 */
12 @Data
13 @ConfigurationProperties(prefix = "spring.datasource.member")
14 public class MemberConfig {
15
16 private String url;
17 private String password;
18 private String username;
19 private String driverClassName;
20 }
1 package com.wuwu.cboot.config;
2
3 import lombok.Data;
4 import org.springframework.boot.context.properties.ConfigurationProperties;
5
6 /**
7 * @Description:订单数据库连接属性
8 * @author: wph
9 * @Version: 1.0
10 * @date: 2021/1/15
11 */
12 @Data
13 @ConfigurationProperties(prefix = "spring.datasource.order")
14 public class OrderConfig {
15
16 private String url;
17 private String password;
18 private String username;
19 private String driverClassName;
20 }
1 package com.wuwu.cboot.config;
2
3 import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource;
4 import lombok.SneakyThrows;
5 import org.apache.ibatis.session.SqlSessionFactory;
6 import org.mybatis.spring.SqlSessionFactoryBean;
7 import org.mybatis.spring.SqlSessionTemplate;
8 import org.mybatis.spring.annotation.MapperScan;
9 import org.springframework.beans.factory.annotation.Qualifier;
10 import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
11 import org.springframework.context.annotation.Bean;
12 import org.springframework.context.annotation.Configuration;
13
14 import javax.sql.DataSource;
15
16 /**
17 * @Description:会员数据源配置
18 * @author: wph
19 * @Version: 1.0
20 * @date: 2021/1/12
21 */
22 @Configuration
23 @MapperScan(basePackages = "com.wuwu.cboot.member.mapper",sqlSessionTemplateRef = "memberSqlSessionTemplate")
24 public class MemberDataSourceConfig {
25
26 /**
27 * @Description: 配置会员数据源
28 * @author: wph
29 * @date: 2021/1/15
30 * @param memberConfig
31 * @return javax.sql.DataSource
32 */
33 @Bean("memberDataSource")
34 public DataSource memberDataSource(MemberConfig memberConfig){
35 //1.创建会员的xaDataSource
36 MysqlXADataSource xaDataSource = new MysqlXADataSource();
37 xaDataSource.setPassword(memberConfig.getPassword());
38 xaDataSource.setUser(memberConfig.getUsername());
39 xaDataSource.setUrl(memberConfig.getUrl());
40 xaDataSource.setPinGlobalTxToPhysicalConnection(true);
41
42 //2.将会员的xaDataSource注册到全局事务上
43 AtomikosDataSourceBean dataSource = new AtomikosDataSourceBean();
44 dataSource.setXaDataSource(xaDataSource);
45
46 return dataSource;
47 }
48
49 /**
50 * @Description: 将会员sqlSessionFactory注入到容器中
51 * @author: wph
52 * @date: 2021/1/13
53 * @param dataSource
54 * @return org.apache.ibatis.session.SqlSessionFactory
55 */
56 @SneakyThrows(Exception.class)
57 @Bean("memberSqlSessionFactory")
58 public SqlSessionFactory memberSqlSessionFactory(@Qualifier("memberDataSource")DataSource dataSource){
59 SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
60 sqlSessionFactoryBean.setDataSource(dataSource);
61 return sqlSessionFactoryBean.getObject();
62 }
63
64 /**
65 * @Description: 创建SqlSessionTemplate模板
66 * @author: wph
67 * @date: 2021/1/18
68 * @param sqlSessionFactory
69 * @return org.mybatis.spring.SqlSessionTemplate
70 */
71 @Bean("memberSqlSessionTemplate")
72 public SqlSessionTemplate memberSqlSessionTemplate(@Qualifier("memberSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
73 return new SqlSessionTemplate(sqlSessionFactory);
74 }
75
76 }
1 package com.wuwu.cboot.config;
2
3 import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource;
4 import lombok.SneakyThrows;
5 import org.apache.ibatis.session.SqlSessionFactory;
6 import org.mybatis.spring.SqlSessionFactoryBean;
7 import org.mybatis.spring.SqlSessionTemplate;
8 import org.mybatis.spring.annotation.MapperScan;
9 import org.springframework.beans.factory.annotation.Qualifier;
10 import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
11 import org.springframework.context.annotation.Bean;
12 import org.springframework.context.annotation.Configuration;
13
14 import javax.sql.DataSource;
15
16 /**
17 * @Description:订单数据源配置
18 * @author: wph
19 * @Version: 1.0
20 * @date: 2021/1/15
21 */
22 @Configuration
23 @MapperScan(basePackages = "com.wuwu.cboot.order.mapper",sqlSessionFactoryRef = "orderSqlSessionFactory")
24 public class OrderDataSourceConfig {
25
26 /**
27 * @Description: 配置订单数据源
28 * @author: wph
29 * @date: 2021/1/15
30 * @param orderConfig
31 * @return javax.sql.DataSource
32 */
33 @Bean("orderDataSource")
34 public DataSource orderDataSource(OrderConfig orderConfig){
35 //1.创建订单xaDataSource
36 MysqlXADataSource xaDataSource = new MysqlXADataSource();
37 xaDataSource.setUrl(orderConfig.getUrl());
38 xaDataSource.setUser(orderConfig.getUsername());
39 xaDataSource.setPassword(orderConfig.getPassword());
40 xaDataSource.setPinGlobalTxToPhysicalConnection(true);
41
42 //将xaDataSource注册到全局事务
43 AtomikosDataSourceBean dataSource = new AtomikosDataSourceBean();
44 dataSource.setXaDataSource(xaDataSource);
45 return dataSource;
46 }
47
48 /**
49 * @Description: 配置session工厂
50 * @author: wph
51 * @date: 2021/1/18
52 * @param dataSource
53 * @return org.apache.ibatis.session.SqlSessionFactory
54 */
55 @SneakyThrows
56 @Bean("orderSqlSessionFactory")
57 public SqlSessionFactory orderSqlSessionFactory(@Qualifier("orderDataSource") DataSource dataSource){
58 SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
59 sqlSessionFactoryBean.setDataSource(dataSource);
60 return sqlSessionFactoryBean.getObject();
61 }
62
63 /**
64 * @Description: 创建SqlSessionTemplate模板
65 * @author: wph
66 * @date: 2021/1/18
67 * @param sqlSessionFactory
68 * @return org.mybatis.spring.SqlSessionTemplate
69 */
70 @Bean("orderSqlSessionTemplate")
71 public SqlSessionTemplate orderSqlSessionTemplate(@Qualifier("orderSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
72 return new SqlSessionTemplate(sqlSessionFactory);
73 }
74
75 }
1 package com.wuwu.cboot.controller;
2
3 import com.wuwu.cboot.service.MemberService;
4 import org.springframework.beans.factory.annotation.Autowired;
5 import org.springframework.web.bind.annotation.RequestMapping;
6 import org.springframework.web.bind.annotation.RestController;
7
8 /**
9 * @Description:会员控制层
10 * @author: wph
11 * @Version: 1.0
12 * @date: 2020/10/26
13 */
14 @RestController
15 public class MemberController {
16
17 @Autowired
18 private MemberService memberService;
19
20 /**
21 * @Description: 新增会员用户
22 * @author: wph
23 * @date: 2021/1/20
24 * @param age
25 * @param name
26 * @return java.lang.Object
27 */
28 @RequestMapping("/saveMember")
29 public Object saveMember(int age,String name){
30 return memberService.saveMember(age,name);
31 }
32 }
1 package com.wuwu.cboot.service.impl;
2
3 import com.wuwu.cboot.member.mapper.MemberMapper;
4 import com.wuwu.cboot.order.mapper.OrderMemberMapper;
5 import com.wuwu.cboot.service.MemberService;
6 import org.springframework.stereotype.Service;
7 import org.springframework.transaction.annotation.Transactional;
8
9 import javax.annotation.Resource;
10
11 /**
12 * @Description:
13 * @author: wph
14 * @Version: 1.0
15 * @date: 2021/1/12
16 */
17 @Service
18 public class MemberServiceImpl implements MemberService {
19
20 @Resource
21 private OrderMemberMapper orderMemberMapper;
22 @Resource
23 private MemberMapper memberMapper;
24
25 @Transactional
26 public String saveMember(int age,String name){
27 //调用会员接口
28 memberMapper.saveMember(age, name);
29 //调用订单接口
30 int i = orderMemberMapper.saveOrder(123, "dawfa");
31 int num = 13 / 0;
32 return i == 1 ? "true" : "false";
33 }
34 }
1 package com.wuwu.cboot.member.mapper;
2
3 import org.apache.ibatis.annotations.Insert;
4 import org.apache.ibatis.annotations.Mapper;
5
6 @Mapper
7 public interface MemberMapper {
8
9 @Insert("insert into member (age,name) values(#{age},#{name})")
10 int saveMember(int age, String name);
1 package com.wuwu.cboot.order.mapper;
2
3 import org.apache.ibatis.annotations.Insert;
4 import org.mybatis.spring.annotation.MapperScan;
5
6 @MapperScan
7 public interface OrderMemberMapper {
8
9 @Insert("insert into order_member (order_id,order_code) values(#{orderId},#{orderCode})")
10 int saveOrder(int orderId, String orderCode);
11 }
1 package com.wuwu.cboot;
2
3 import com.wuwu.cboot.config.MemberConfig;
4 import com.wuwu.cboot.config.OrderConfig;
5 import org.springframework.boot.SpringApplication;
6 import org.springframework.boot.autoconfigure.SpringBootApplication;
7 import org.springframework.boot.context.properties.EnableConfigurationProperties;
8
9 @SpringBootApplication
10 @EnableConfigurationProperties({MemberConfig.class, OrderConfig.class})
11 public class CbootApplication {
12
13 public static void main(String[] args) {
14 SpringApplication.run(CbootApplication.class, args);
15 }
16
17 }
文章标题:springboot2.0 解决多数据源分布式事务问题
文章链接:http://soscw.com/index.php/essay/59947.html