基于Spring Boot的多数据源切换,通过事务管理器对多个数据源切换进行事务管理,手动添加事务应用于一个list集合插入到DB1和DB2,其中一个DB失败则对两个DB的事务都进行回滚,对此列出详细代码
时间: 2024-02-11 21:05:14 浏览: 70
好的,下面是基于Spring Boot的多数据源切换,通过事务管理器对多个数据源切换进行事务管理,手动添加事务应用于一个list集合插入到DB1和DB2,其中一个DB失败则对两个DB的事务都进行回滚的详细代码:
首先,在application.yml文件中配置两个数据源,例如:
```
spring:
datasource:
test1:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: root
test2:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/test2?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: root
```
然后,创建两个数据源的配置类,例如:
```
@Configuration
@MapperScan(basePackages = "com.example.demo.mapper.test1", sqlSessionTemplateRef = "test1SqlSessionTemplate")
public class Test1DataSourceConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource.test1")
public DataSource test1DataSource() {
return DataSourceBuilder.create().build();
}
@Bean
public SqlSessionFactory test1SqlSessionFactory(@Qualifier("test1DataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/test1/*.xml"));
return bean.getObject();
}
@Bean
public SqlSessionTemplate test1SqlSessionTemplate(@Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
@Bean(name = "test1TransactionManager")
public DataSourceTransactionManager test1TransactionManager(@Qualifier("test1DataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
@Configuration
@MapperScan(basePackages = "com.example.demo.mapper.test2", sqlSessionTemplateRef = "test2SqlSessionTemplate")
public class Test2DataSourceConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource.test2")
public DataSource test2DataSource() {
return DataSourceBuilder.create().build();
}
@Bean
public SqlSessionFactory test2SqlSessionFactory(@Qualifier("test2DataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/test2/*.xml"));
return bean.getObject();
}
@Bean
public SqlSessionTemplate test2SqlSessionTemplate(@Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
@Bean(name = "test2TransactionManager")
public DataSourceTransactionManager test2TransactionManager(@Qualifier("test2DataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
```
其中,@MapperScan注解用于指定Mapper接口的扫描路径,@Qualifier注解用于指定注入的Bean名称。
接着,创建DAO层接口和实现类,例如:
```
public interface Test1Mapper {
int insert(Test1 test1);
}
public interface Test2Mapper {
int insert(Test2 test2);
}
@Repository
public class Test1MapperImpl implements Test1Mapper {
@Autowired
private SqlSessionTemplate test1SqlSessionTemplate;
@Override
public int insert(Test1 test1) {
return test1SqlSessionTemplate.insert("com.example.demo.mapper.test1.Test1Mapper.insert", test1);
}
}
@Repository
public class Test2MapperImpl implements Test2Mapper {
@Autowired
private SqlSessionTemplate test2SqlSessionTemplate;
@Override
public int insert(Test2 test2) {
return test2SqlSessionTemplate.insert("com.example.demo.mapper.test2.Test2Mapper.insert", test2);
}
}
```
然后,创建Service层接口和实现类,例如:
```
public interface TestService {
void insert(List<Test1> test1List, List<Test2> test2List) throws Exception;
}
@Service
public class TestServiceImpl implements TestService {
@Autowired
private Test1Mapper test1Mapper;
@Autowired
private Test2Mapper test2Mapper;
@Autowired
@Qualifier("test1TransactionManager")
private PlatformTransactionManager test1TransactionManager;
@Autowired
@Qualifier("test2TransactionManager")
private PlatformTransactionManager test2TransactionManager;
@Override
@Transactional(rollbackFor = Exception.class)
public void insert(List<Test1> test1List, List<Test2> test2List) throws Exception {
TransactionStatus test1TransactionStatus = null;
TransactionStatus test2TransactionStatus = null;
DefaultTransactionDefinition test1TransactionDefinition = new DefaultTransactionDefinition();
DefaultTransactionDefinition test2TransactionDefinition = new DefaultTransactionDefinition();
test1TransactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
test2TransactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
try {
test1TransactionStatus = test1TransactionManager.getTransaction(test1TransactionDefinition);
for (Test1 test1 : test1List) {
test1Mapper.insert(test1);
}
test2TransactionStatus = test2TransactionManager.getTransaction(test2TransactionDefinition);
for (Test2 test2 : test2List) {
test2Mapper.insert(test2);
}
test1TransactionManager.commit(test1TransactionStatus);
test2TransactionManager.commit(test2TransactionStatus);
} catch (Exception e) {
if (test1TransactionStatus != null) {
test1TransactionManager.rollback(test1TransactionStatus);
}
if (test2TransactionStatus != null) {
test2TransactionManager.rollback(test2TransactionStatus);
}
throw e;
}
}
}
```
其中,@Transactional注解用于指定事务管理器和回滚策略,test1TransactionManager和test2TransactionManager分别对应不同的数据源的事务管理器,test1TransactionStatus和test2TransactionStatus分别对应不同的数据源的事务状态。
最后,创建Controller层接口和实现类,例如:
```
@RestController
public class TestController {
@Autowired
private TestService testService;
@PostMapping("/test")
public void test(@RequestBody TestRequest request) throws Exception {
testService.insert(request.getTest1List(), request.getTest2List());
}
}
public class TestRequest {
private List<Test1> test1List;
private List<Test2> test2List;
// getter和setter方法省略
}
```
至此,就完成了基于Spring Boot的多数据源切换,通过事务管理器对多个数据源切换进行事务管理,手动添加事务应用于一个list集合插入到DB1和DB2,其中一个DB失败则对两个DB的事务都进行回滚的代码实现。
阅读全文