目录
- 八、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.Driver
url: jdbc:mysql://192.168.239.11:3306/nonghang?serverTimezone=UTC
username: root
password: houchen
jian:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.239.11:3306/jianhang?serverTimezone=UTC
username: root
password: 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
*/
@Bean
public SqlSessionFactory nongFactory(@Qualifier("nongDataSource") DruidDataSource dataSource) throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
return sqlSessionFactoryBean.getObject();
}
@Bean
public 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: true
registry:
type: file
config:
type: file
service:
vgroup-mapping:
default_tx_group: default
grouplist:
default: 127.0.0.1:8091
disable-global-transaction: false #默认为false 可以不配置
application-id: abc # 初始化TM和RM使用
tx-service-group: default_tx_group
enable-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
*/
@Bean
public DataSourceProxyXA nongXA(@Qualifier("nongDataSource") DruidDataSource dataSource){
return new DataSourceProxyXA(dataSource);
}
/**
* ⼿动代理建⾏数据源
* @param dataSource
* @return
*/
@Bean
public DataSourceProxyXA jianXA(@Qualifier("jianDataSource") DruidDataSource dataSource){
return new DataSourceProxyXA(dataSource);
}
/**
* 配置NongSqlSession
*/
/*@Bean
public SqlSessionFactory nongFactory(@Qualifier("nongDataSource") DruidDataSource dataSource) throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
return sqlSessionFactoryBean.getObject();
}
@Bean
public SqlSessionFactory jianFactory(@Qualifier("jianDataSource") DruidDataSource dataSource) throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
return sqlSessionFactoryBean.getObject();
}*/
/**
* 配置NongSqlSession
*/
@Bean
public SqlSessionFactory nongFactory(@Qualifier("nongXA") DataSource dataSource) throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
return sqlSessionFactoryBean.getObject();
}
@Bean
public SqlSessionFactory jianFactory(@Qualifier("jianXA") DataSource dataSource) throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
return sqlSessionFactoryBean.getObject();
}
}