SpringBoot多数据库事务管理

0

如果SpringBoot同时加入多个数据源,不能正确获取事务管理器,可以使用下面方法处理:

/**
 * 配置事务
 * 
 * 配置JDBC事务事务为默认的事务,Neo4j事务需要手动指定`@Transactional(transactionManager = "neo4jTransactionManager")`。
 * 
 * @author acgist
 */
@Configuration(proxyBeanMethods = false)
@Import({DataSourceAutoConfiguration.class, MybatisPlusAutoConfiguration.class})
//@Import({DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, MybatisPlusAutoConfiguration.class})
public class TransactionConfiguration {
	
	@Bean("transactionManager")
	@Primary
	public DataSourceTransactionManager transactionManager(
		Environment environment,
		DataSource dataSource,
		ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers
	) {
		final DataSourceTransactionManager transactionManager = this.createTransactionManager(environment, dataSource);
		transactionManagerCustomizers.ifAvailable((customizers) -> customizers.customize(transactionManager));
		return transactionManager;
	}
	
	private DataSourceTransactionManager createTransactionManager(Environment environment, DataSource dataSource) {
		return
			environment.getProperty("spring.dao.exceptiontranslation.enable", Boolean.class, Boolean.TRUE)
			?
			new JdbcTransactionManager(dataSource)
			:
			new DataSourceTransactionManager(dataSource);
	}
	
	@Bean("neo4jTransactionManager")
	public Neo4jTransactionManager transactionManager(
		Driver driver,
		DatabaseSelectionProvider databaseNameProvider,
		ObjectProvider<TransactionManagerCustomizers> optionalCustomizers
	) {
		final Neo4jTransactionManager transactionManager = new Neo4jTransactionManager(driver, databaseNameProvider);
		optionalCustomizers.ifAvailable((customizer) -> customizer.customize(transactionManager));
		return transactionManager;
	}
	
}

默认使用JDBC事务管理器,如果使用Neo4j,可以指定事务管理器@Transactional(transactionManager = "neo4jTransactionManager")

还可以这样配置:

@Slf4j
@Configuration(proxyBeanMethods = false)
@Import({DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, MybatisPlusAutoConfiguration.class})
public class TransactionConfiguration {
	
	/**
	 * 配置PrimaryBean
	 * 
	 * @author acgist
	 */
	private static class PrimaryBeanPostProcessor implements BeanDefinitionRegistryPostProcessor {

		@Override
		public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
			final BeanDefinition beanDefinition = beanFactory.getBeanDefinition("transactionManager");
			beanDefinition.setPrimary(true);
			log.info("设置primary事务:{}", beanDefinition.getFactoryBeanName());
		}

		@Override
		public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
		}

	}
	
	@Bean(name = "primaryBeanPostProcessor")
	public BeanDefinitionRegistryPostProcessor primaryBeanPostProcessor() {
		return new PrimaryBeanPostProcessor();
	}

	@Bean("neo4jTransactionManager")
	public Neo4jTransactionManager neo4jTransactionManager(
		Driver driver,
		DatabaseSelectionProvider databaseNameProvider,
		ObjectProvider<TransactionManagerCustomizers> optionalCustomizers
	) {
		final Neo4jTransactionManager transactionManager = new Neo4jTransactionManager(driver, databaseNameProvider);
		optionalCustomizers.ifAvailable((customizer) -> customizer.customize(transactionManager));
		return transactionManager;
	}
	
}