Spring如何为多数据源配置多个事务管理器?
1.配置多个数据源
配置多个数据源的信息,可以使用xml、json、配置中心、zookeeper、数据库加载等多种方式,例如在application.properties中配置多个数据源:
# 数据源1
spring.datasource.db1.url=jdbc:mysql://localhost:3306/db1?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
spring.datasource.db1.username=root
spring.datasource.db1.password=root
spring.datasource.db1.driver-class-name=com.mysql.jdbc.Driver# 数据源2
spring.datasource.db2.url=jdbc:mysql://localhost:3306/db2?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
spring.datasource.db2.username=root
spring.datasource.db2.password=root
spring.datasource.db2.driver-class-name=com.mysql.jdbc.Driver
2.创建数据源配置类
分别创建两个数据源配置类,并分别指定数据源配置前缀:
@Configuration
public class DataSourceConfig {@Bean(name = "db1DataSource")@ConfigurationProperties(prefix = "spring.datasource.db1")public DataSource db1DataSource() {return DataSourceBuilder.create().build();}@Bean(name = "db2DataSource")@ConfigurationProperties(prefix = "spring.datasource.db2")public DataSource db2DataSource() {return DataSourceBuilder.create().build();}
}
3.创建多个事务管理器
创建两个事务管理器,并分别指定对应的数据源:
@Configuration
public class TransactionManagerConfig {@Autowired@Qualifier("db1DataSource")private DataSource db1DataSource;@Autowired@Qualifier("db2DataSource")private DataSource db2DataSource;@Bean(name = "db1TransactionManager")public DataSourceTransactionManager db1TransactionManager() {return new DataSourceTransactionManager(db1DataSource);}@Bean(name = "db2TransactionManager")public DataSourceTransactionManager db2TransactionManager() {return new DataSourceTransactionManager(db2DataSource);}
}
4.创建多个JdbcTemplate
创建两个JdbcTemplate,并分别指定对应的数据源:
@Configuration
public class JdbcTemplateConfig {@Autowired@Qualifier("db1DataSource")private DataSource db1DataSource;@Autowired@Qualifier("db2DataSource")private DataSource db2DataSource;@Bean(name = "db1JdbcTemplate")public JdbcTemplate db1JdbcTemplate() {return new JdbcTemplate(db1DataSource);}@Bean(name = "db2JdbcTemplate")public JdbcTemplate db2JdbcTemplate() {return new JdbcTemplate(db2DataSource);}
}
如果使用MyBatis,可以顺带配置一下SqlSessionFactory:
@Bean(name = "db1SqlSessionFactory")public SqlSessionFactory db1SqlSessionFactory(@Value("${mybatis.db1.mapper-locations}") String mapperLocations) throws Exception {SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();sessionFactoryBean.setDataSource(db1DataSource);sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocations));// 设置MyBatis配置文件位置sessionFactoryBean.setConfigLocation(new ClassPathResource("mybatis-config.xml"));return sessionFactoryBean.getObject();}@Bean(name = "db2SqlSessionFactory")public SqlSessionFactory db2SqlSessionFactory(@Value("${mybatis.db2.mapper-locations}") String mapperLocations) throws Exception {SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();sessionFactoryBean.setDataSource(db2DataSource);sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocations));// 设置MyBatis配置文件位置sessionFactoryBean.setConfigLocation(new ClassPathResource("mybatis-config.xml"));return sessionFactoryBean.getObject();}
使用事务:
@Transactional(transactionManager = "db1TransactionManager", rollbackFor = Exception.class)public void insertDb1(String name) {db1JdbcTemplate.update("INSERT INTO test (name) VALUES (?)", name);}@Transactional(transactionManager = "db2TransactionManager", rollbackFor = Exception.class)public void insertDb2(String name) {db2JdbcTemplate.update("INSERT INTO test (name) VALUES (?)", name);}
到目前为止,一切都很顺利,问题来了:
如果架构上数据库采用主从模式,那么如何配置事务管理器?
一般主库负责写,从库负责读,事务管理器主要作用是能在异常时回滚业务代码,读数据没有回滚业务代码的必要,所以主从模式下不需要为主从数据源都配置事务管理器,只需要为主库配置事务管理即可。
本文链接:https://my.lmcjl.com/post/11032.html
展开阅读全文
4 评论