1.问题发现
在之前的项目中,一直都是单数据源项目,只要在yaml配置文件中,配置好了数据库信息,即可使用Spring的@Transactional注解触发事务。
但这次接手的项目需要用到两个数据源,除了需要在yaml配置文件中,做好数据库信息配置以外,还需要在代码层做一个配置config的配置,给不同的数据源做一个事务管理器,才能触发事务。
2.实战
2.1配置
application.yaml:
yaml
spring:
datasource:
csdbg1:
driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc-url: jdbc:sqlserver://localhost:1433; DatabaseName=csdbg1;encrypt=false;useUnicode=true;characterEncoding=utf-8?rewriteBatchedStatements=true
username: admin
password: 123456
csdbg7:
driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc-url: jdbc:sqlserver://localhost:1433; DatabaseName=csdbg7;encrypt=false;useUnicode=true;characterEncoding=utf-8?rewriteBatchedStatements=true
username: admin
password: 123456
config:
@EnableJpaRepositories的basePackages 是DAO层的包位置,不同的数据源,需要创建不同的包。
EntityManagerFactoryBuilder的packages设置实体类包的位置,不同的数据源,需要创建不同的包。
数据源1的config
java
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "org.rx.gosc.mapper.gosc.g1", entityManagerFactoryRef = "csdbG1EntityManagerFactory", transactionManagerRef = "csdbG1TransactionManager")
public class CSDBG1JpaConfig {
@Resource
private JpaProperties jpaProperties;
@Primary
@Bean(name = "csdbG1DataSource")
@ConfigurationProperties(prefix = "spring.datasource.csdbg1")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Primary
@Bean(name = "csdbG1EntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(EntityManagerFactoryBuilder builder, @Qualifier("csdbG1DataSource") DataSource dataSource) {
return builder
// 设置数据源
.dataSource(dataSource)
// 设置jpa配置
.properties(jpaProperties.getProperties())
// 设置实体包名
.packages("org.rx.gosc.pojo.entity.gosc.g1")
// 设置持久化单元名,用于@PersistenceContext注解获取EntityManager时指定数据源
.persistenceUnit("csdbg1").build();
}
@Primary
@Bean(name = "csdbG1EntityManager")
public EntityManager entityManager(@Qualifier("csdbG1EntityManagerFactory") EntityManagerFactory factory) {
return factory.createEntityManager();
}
@Primary
@Bean(name = "csdbG1TransactionManager")
public PlatformTransactionManager customerTransactionManager(@Qualifier("csdbG1EntityManagerFactory") EntityManagerFactory csdbrEntityManagerFactory) {
return new JpaTransactionManager(csdbrEntityManagerFactory);
}
@Primary
@Bean(name = "csdbG1JdbcTemplate")
public JdbcTemplate csdbJdbcTemplate(@Qualifier("csdbG1DataSource") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
@Bean(name = "csdbG1TransactionTemplate")
@Primary
public TransactionTemplate primaryTransactionTemplate(@Qualifier("csdbG1TransactionManager") PlatformTransactionManager transactionManager) {
// 创建主数据源的 TransactionTemplate,绑定主事务管理器
TransactionTemplate template = new TransactionTemplate(transactionManager);
// 可选:设置事务传播行为、隔离级别等
template.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
template.setIsolationLevel(TransactionDefinition.ISOLATION_DEFAULT);
return template;
}
}
数据源2的config
java
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "org.rx.gosc.mapper.gosc.g7", entityManagerFactoryRef = "csdbG7EntityManagerFactory", transactionManagerRef = "csdbG7TransactionManager")
public class CSDBG7JpaConfig {
@Resource
private JpaProperties jpaProperties;
@Bean(name = "csdbG7DataSource")
@ConfigurationProperties(prefix = "spring.datasource.csdbg7")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "csdbG7EntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(EntityManagerFactoryBuilder builder, @Qualifier("csdbG7DataSource") DataSource dataSource) {
return builder
// 设置数据源
.dataSource(dataSource)
// 设置jpa配置
.properties(jpaProperties.getProperties())
// 设置实体包名
.packages("org.rx.gosc.pojo.entity.gosc.g7")
// 设置持久化单元名,用于@PersistenceContext注解获取EntityManager时指定数据源
.persistenceUnit("csdbg7").build();
}
@Bean(name = "csdbG7EntityManager")
public EntityManager entityManager(@Qualifier("csdbG7EntityManagerFactory") EntityManagerFactory factory) {
return factory.createEntityManager();
}
@Bean(name = "csdbG7TransactionManager")
public PlatformTransactionManager customerTransactionManager(@Qualifier("csdbG7EntityManagerFactory") EntityManagerFactory csdbrEntityManagerFactory) {
return new JpaTransactionManager(csdbrEntityManagerFactory);
}
@Bean(name = "csdbG7JdbcTemplate")
public JdbcTemplate csdbg7JdbcTemplate(@Qualifier("csdbG7DataSource") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
@Bean(name = "csdbG7TransactionTemplate")
@Primary
public TransactionTemplate primaryTransactionTemplate(@Qualifier("csdbG7TransactionManager") PlatformTransactionManager transactionManager) {
// 创建主数据源的 TransactionTemplate,绑定主事务管理器
TransactionTemplate template = new TransactionTemplate(transactionManager);
// 可选:设置事务传播行为、隔离级别等
template.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
template.setIsolationLevel(TransactionDefinition.ISOLATION_DEFAULT);
return template;
}
}
2.2使用
在@Transactional注解中,添加事务管理器,即可使Service触发回滚,事务管理器是刚刚在config中已配置好了,如:@Transactional(transactionManager = "csdbG1TransactionManager")