目录
- 八、Seata的XA模式
- 8.3 ==XA模式多数据源场景==
- 1 环境搭建
- 2、使⽤XA模式解决事务
八、Seata的XA模式
8.3 XA模式多数据源场景
1 环境搭建
-
建库建表
代码的db.sql中 -
创建工程
-
添加依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.1</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.8</version></dependency>
- 编写主配置类
@SpringBootApplication
public class XAMultiApp {public static void main(String[] args) {SpringApplication.run(XAMultiApp.class);}
}
- 配置文件
server:port: 8080
spring:datasource:nong:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://192.168.239.11:3306/nonghang?serverTimezone=UTCusername: rootpassword: houchenjian:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://192.168.239.11:3306/jianhang?serverTimezone=UTCusername: rootpassword: houchen
logging:level:com:hc: debug
-
mapper + 业务代码
见上述 gitee 仓库 -
编写多数据源配置
@SpringBootConfiguration
@MapperScans({@MapperScan(basePackages = "com.hc.nong", sqlSessionFactoryRef = "nongFactory"), @MapperScan(basePackages = "com.hc.jian", sqlSessionFactoryRef = "jianFactory")})
public class DbConfig {@Bean@ConfigurationProperties(prefix = "spring.datasource.nong")public DruidDataSource nongDataSource() {return new DruidDataSource();}@Bean@ConfigurationProperties(prefix = "spring.datasource.jian")public DruidDataSource jianDataSource() {return new DruidDataSource();}/*** 配置NongSqlSession*/@Beanpublic SqlSessionFactory nongFactory(@Qualifier("nongDataSource") DruidDataSource dataSource) throws Exception {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dataSource);return sqlSessionFactoryBean.getObject();}@Beanpublic SqlSessionFactory jianFactory(@Qualifier("jianDataSource") DruidDataSource dataSource) throws Exception {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dataSource);return sqlSessionFactoryBean.getObject();}}
2、使⽤XA模式解决事务
- 添加依赖
<dependency><groupId>io.seata</groupId><artifactId>seata-spring-boot-starter</artifactId><version>1.5.2</version></dependency>
- yaml文件
注意:
我们添加的是seata-spring-boot-starter
依赖⽀持registry.conf和 file.conf 同时也⽀持把配置编写在application.yml中
但是:
当我们添加的是seata-all依赖时 我们需要添加registry.conf和 file.conf 不能使⽤yml格式配置
因为seata-all没有⾃动配置 所以依赖的不同的包 配置是不同的
seata:enabled: trueregistry:type: fileconfig:type: fileservice:vgroup-mapping:default_tx_group: defaultgrouplist:default: 127.0.0.1:8091disable-global-transaction: false #默认为false 可以不配置application-id: abc # 初始化TM和RM使用tx-service-group: default_tx_groupenable-auto-data-source-proxy: true # 设置datasource自动代理data-source-proxy-mode: XA # 指定代理模式 XA
-
⾃动代理的⽅式
就是上面yaml文件的最后两行配置 -
业务代码上面添加注解
@GlobalTransactional(rollbackFor = Exception.class)public void transfer(int fromId, int toId, double monoey) {nongMapper.reduceMoney(fromId, monoey);int i = 10 / 0;jianMapper.increaseMoney(toId, monoey);}
- 测试
调用接口 http://localhost:8080/user/transfer?fromId=1&toId=1&monoey=100,查看日志
⼿动代理的⽅式
-
修改配置关闭⾃动代理
-
⼿动构建代理数据源
@SpringBootConfiguration
@MapperScans({@MapperScan(basePackages = "com.hc.nong", sqlSessionFactoryRef = "nongFactory"), @MapperScan(basePackages = "com.hc.jian", sqlSessionFactoryRef = "jianFactory")})
public class DbConfig {@Bean@ConfigurationProperties(prefix = "spring.datasource.nong")public DruidDataSource nongDataSource() {return new DruidDataSource();}@Bean@ConfigurationProperties(prefix = "spring.datasource.jian")public DruidDataSource jianDataSource() {return new DruidDataSource();}/*** ⼿动配置农⾏代理数据源* @param dataSource* @return*/@Beanpublic DataSourceProxyXA nongXA(@Qualifier("nongDataSource") DruidDataSource dataSource){return new DataSourceProxyXA(dataSource);}/*** ⼿动代理建⾏数据源* @param dataSource* @return*/@Beanpublic DataSourceProxyXA jianXA(@Qualifier("jianDataSource") DruidDataSource dataSource){return new DataSourceProxyXA(dataSource);}/*** 配置NongSqlSession*//*@Beanpublic SqlSessionFactory nongFactory(@Qualifier("nongDataSource") DruidDataSource dataSource) throws Exception {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dataSource);return sqlSessionFactoryBean.getObject();}@Beanpublic SqlSessionFactory jianFactory(@Qualifier("jianDataSource") DruidDataSource dataSource) throws Exception {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dataSource);return sqlSessionFactoryBean.getObject();}*//*** 配置NongSqlSession*/@Beanpublic SqlSessionFactory nongFactory(@Qualifier("nongXA") DataSource dataSource) throws Exception {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dataSource);return sqlSessionFactoryBean.getObject();}@Beanpublic SqlSessionFactory jianFactory(@Qualifier("jianXA") DataSource dataSource) throws Exception {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dataSource);return sqlSessionFactoryBean.getObject();}
}