一、预备知识
首先放一个关于基础spring事务管理机制的说明博客https://www.marcobehler.com/guides/spring-transaction-management-transactional-in-depth。
总的来说,spring通过委托自己的事务管理给TransactionManager对象来进行事务的抽象,以及与不同框架的整合(通过不同的TransactionManager实现)
二、具体实现
这个实现只是适用于多数据源,但是多个数据源之间不存在分布式事务的场景
具体代码编写的过程中参靠了这边博客
https://blog.csdn.net/yuzongtao/article/details/88888607
下面是我的代码,首先是数据源,JdbcTemplate,以及适用于JdbcTemplate的事务管理器,DataSourceTransactionManager
import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DataSourceTransactionManager; @Configuration public class DataSourceConfig { /** * b数据源 * @return */ @Bean(name = "bDataSource") @Qualifier("bDataSource") @ConfigurationProperties(prefix="spring.datasource.b") public DataSource primaryDataSource() { return DataSourceBuilder.create().build(); } /** * a数据源 * @return */ @Bean(name = "aDataSource") @Qualifier("aDataSource") @Primary @ConfigurationProperties(prefix="spring.datasource.a") public DataSource secondaryDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "bJdbcTemplate") public JdbcTemplate primaryJdbcTemplate( @Qualifier("bDataSource") DataSource dataSource) { return new JdbcTemplate(dataSource); } @Bean(name = "aJdbcTemplate") public JdbcTemplate secondaryJdbcTemplate( @Qualifier("aDataSource") DataSource dataSource) { return new JdbcTemplate(dataSource); } //事务管理器 @Bean(name = "bTransactionManager") @Qualifier("bTransactionManager") public DataSourceTransactionManager bTransactionManager(@Qualifier("bDataSource") DataSource bDataSource) { return new DataSourceTransactionManager(bDataSource); } @Bean(name = "aTransactionManager") @Qualifier("aTransactionManager") public DataSourceTransactionManager aTransactionManager(@Qualifier("aDataSource") DataSource aDataSource) { return new DataSourceTransactionManager(aDataSource); } }
具体的application.properties就不贴了,自己自定义一个前缀即可,我这里使用
#数据库配置信息,多数据源配置 #b_test库 spring.datasource.b.jdbc-url=jdbc:mysql://192.168.2.234:3306/b_test?serverTimezone=Asia/Shanghai&cachePrepStmts=true&prepStmtCacheSize=250&prepStmtCacheSqlLimit=2048&useServerPrepStmts=true&useLocalSessionState=true&rewriteBatchedStatements=true&cacheResultSetMetadata=true&maintainTimeStats=false spring.datasource.b.username=root spring.datasource.b.password=root spring.datasource.b.driver-class-name=com.mysql.cj.jdbc.Driver #a_test库 spring.datasource.a.jdbc-url=jdbc:mysql://192.168.2.234:3306/a_test?serverTimezone=Asia/Shanghai&cachePrepStmts=true&prepStmtCacheSize=250&prepStmtCacheSqlLimit=2048&useServerPrepStmts=true&useLocalSessionState=true&rewriteBatchedStatements=true&cacheResultSetMetadata=true&maintainTimeStats=false spring.datasource.a.username=root spring.datasource.a.password=root spring.datasource.a.driver-class-name=com.mysql.cj.jdbc.Driver
最后一个单词同springboot自动配置情况,具体可以使用STS或者idea进行提示即可
具体使用则需要在@Transactional显式指明使用哪个事务管理器
@Transactional(transactionManager = "aTransactionManager")//指定事务管理器,测试通过 public Map<String, Object> saveLayout(String useruuid, String layout) { resCount = userDao.saveLayout(useruuid, layout); //测试事务管理器是否生效 //int i = 1/0 return resMsg; }
通过指定transactionManager分别为aTransactionManager以及bTransactionManager,采用int i = 1/0 抛出运行时异常即可确定配置事务是否生效