基于Spring Boot的多数据源切换,通过创建事务管理器对多个数据源切换进行事务管理,手动添加事务应用于两个数据源,中间对两个数据源进行切换并对数据源的一张表插入删除等操作,其中一个数据源失败则对两个数据源全部事务都进行回滚,对此列出详细代码
时间: 2024-01-22 17:04:05 浏览: 28
好的,下面是详细的代码实现:
首先,在Spring Boot项目中,需要在pom.xml中添加以下依赖:
```xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
```
然后,在application.properties文件中配置多数据源:
```properties
# 第一个数据源
spring.datasource.url=jdbc:mysql://localhost:3306/db1?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# 第二个数据源
db2.datasource.url=jdbc:mysql://localhost:3306/db2?useUnicode=true&characterEncoding=utf-8&useSSL=false
db2.datasource.username=root
db2.datasource.password=root
db2.datasource.driver-class-name=com.mysql.jdbc.Driver
```
接着,定义两个数据源的配置类:
```java
@Configuration
@MapperScan(basePackages = "com.example.demo.mapper1", sqlSessionTemplateRef = "db1SqlSessionTemplate")
public class Db1DataSourceConfig {
@Bean(name = "db1DataSource")
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource db1DataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "db1SqlSessionFactory")
public SqlSessionFactory db1SqlSessionFactory(@Qualifier("db1DataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
return bean.getObject();
}
@Bean(name = "db1TransactionManager")
public DataSourceTransactionManager db1TransactionManager(@Qualifier("db1DataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "db1SqlSessionTemplate")
public SqlSessionTemplate db1SqlSessionTemplate(@Qualifier("db1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
```
```java
@Configuration
@MapperScan(basePackages = "com.example.demo.mapper2", sqlSessionTemplateRef = "db2SqlSessionTemplate")
public class Db2DataSourceConfig {
@Bean(name = "db2DataSource")
@ConfigurationProperties(prefix = "db2.datasource")
public DataSource db2DataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "db2SqlSessionFactory")
public SqlSessionFactory db2SqlSessionFactory(@Qualifier("db2DataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
return bean.getObject();
}
@Bean(name = "db2TransactionManager")
public DataSourceTransactionManager db2TransactionManager(@Qualifier("db2DataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "db2SqlSessionTemplate")
public SqlSessionTemplate db2SqlSessionTemplate(@Qualifier("db2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
```
其中,@MapperScan注解用于扫描Mapper接口,@ConfigurationProperties注解用于读取application.properties中的配置。
最后,定义一个测试类:
```java
@Service
@Transactional
public class TestService {
@Autowired
private Db1Mapper db1Mapper;
@Autowired
private Db2Mapper db2Mapper;
public void test() {
// 在第一个数据源中插入一条记录
db1Mapper.insert(new User("db1", "123456"));
// 在第二个数据源中插入一条记录
db2Mapper.insert(new User("db2", "123456"));
// 在第二个数据源中删除一条记录,模拟失败
db2Mapper.deleteByName("db2");
// 在第一个数据源中更新一条记录,模拟失败
db1Mapper.updateByName("db1", "654321");
// 提交事务,如果有任何一个数据源操作失败,则两个数据源的事务都会回滚
// 如果两个数据源的操作都成功,则两个数据源的事务都会提交
}
}
```
在上述代码中,@Transactional注解用于开启事务。在test()方法中,先在第一个数据源中插入一条记录,然后在第二个数据源中插入一条记录。接着,删除第二个数据源中的一条记录,模拟操作失败。最后,在第一个数据源中更新一条记录,也模拟操作失败。这样,就可以测试两个数据源的事务是否能够正常回滚。
希望这份代码能够对你有所帮助。