老师,能帮我看一下吗?两个spring data jpa数据源共用一个jtaTransactionManager出问题啦~
来源:4-9 JTA多数据源事务实例
他门说这就是人生
2019-12-16
我想测试两个MySQL数据库的多数据源事务,配置了两个spring data jpa数据源。如下:
@Configuration
@PropertySource({ "classpath:persistence-multiple-db.properties" })
@EnableJpaRepositories(
basePackages = "com.gaojingsi.transaction.muiltidatasourcetransactiondemo.repository.db2",
entityManagerFactoryRef = "db2EntityManager",
transactionManagerRef = "jtaTransactionManager"
)
public class Db2Config {
@Autowired
private Environment env;
@Bean
@Primary
public LocalContainerEntityManagerFactoryBean db2EntityManager() {
LocalContainerEntityManagerFactoryBean em
= new LocalContainerEntityManagerFactoryBean();
em.setDataSource(db2DataSource());
em.setPackagesToScan(
new String[] { "com.gaojingsi.transaction.muiltidatasourcetransactiondemo.entity.db2" });
HibernateJpaVendorAdapter vendorAdapter
= new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
HashMap<String, Object> properties = new HashMap<>();
properties.put("hibernate.hbm2ddl.auto",
env.getProperty("hibernate.hbm2ddl.auto"));
properties.put("hibernate.dialect",
env.getProperty("hibernate.dialect"));
em.setJpaPropertyMap(properties);
return em;
}
@Primary
@Bean
public DataSource db2DataSource() {
DriverManagerDataSource dataSource
= new DriverManagerDataSource();
dataSource.setDriverClassName(
env.getProperty("db2.driver-class-name"));
dataSource.setUrl(env.getProperty("db2.jdbc-url"));
dataSource.setUsername(env.getProperty("db2.username"));
dataSource.setPassword(env.getProperty("db2.password"));
return dataSource;
}
// @Primary
// @Bean
// public PlatformTransactionManager db2TransactionManager() {
//
// JpaTransactionManager transactionManager
// = new JpaTransactionManager();
// transactionManager.setEntityManagerFactory(
// db2EntityManager().getObject());
// return transactionManager;
// }
}@Configuration
@PropertySource({ "classpath:persistence-multiple-db.properties" })
@EnableJpaRepositories(
basePackages = "com.gaojingsi.transaction.muiltidatasourcetransactiondemo.repository.db1",
entityManagerFactoryRef = "db1EntityManager",
transactionManagerRef = "jtaTransactionManager"
)
public class Db1Config {
@Autowired
private Environment env;
@Bean
public LocalContainerEntityManagerFactoryBean db1EntityManager() {
LocalContainerEntityManagerFactoryBean em
= new LocalContainerEntityManagerFactoryBean();
em.setDataSource(db1DataSource());
em.setPackagesToScan(
new String[] { "com.gaojingsi.transaction.muiltidatasourcetransactiondemo.entity.db1" });
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
HashMap<String, Object> properties = new HashMap<>();
properties.put("hibernate.hbm2ddl.auto",
env.getProperty("hibernate.hbm2ddl.auto"));
properties.put("hibernate.dialect",
env.getProperty("hibernate.dialect"));
em.setJpaPropertyMap(properties);
return em;
}
@Bean
public DataSource db1DataSource() {
DriverManagerDataSource dataSource
= new DriverManagerDataSource();
dataSource.setDriverClassName(
env.getProperty("db1.driver-class-name"));
dataSource.setUrl(env.getProperty("db1.jdbc-url"));
dataSource.setUsername(env.getProperty("db1.username"));
dataSource.setPassword(env.getProperty("db1.password"));
return dataSource;
}
// @Bean
// public PlatformTransactionManager db1TransactionManager() {
//
// JpaTransactionManager transactionManager
// = new JpaTransactionManager();
// transactionManager.setEntityManagerFactory(
// db1EntityManager().getObject());
// return transactionManager;
// }
}还配置了一个公共的PlatformTransactionManager:
@Configuration
@EnableTransactionManagement
public class WebConfig implements WebMvcConfigurer {
@Bean(name = "jtaTransactionManager")
public PlatformTransactionManager jtaTransactionManager() {
UserTransactionManager userTransactionManager = new UserTransactionManager();
UserTransaction userTransaction = new UserTransactionImp();
return new JtaTransactionManager(userTransaction, userTransactionManager);
}
}如果在@EnableJpaRepositories的transactionManagerRef中,各用各的transactionManager,两个数据库都能成功插入数据,但没法保障两个数据库的事务。
所以我配置了一个jtaTransactionManager,希望两个数据源共用这个jtaTransactionManager,结果在没有异常和错误的情况下也只有一个数据库的操作生效。不知道如何测试两个MySQL数据库的事务,并保证一致性和原子性。
ps:
我的demo在gitee上:
https://gitee.com/feitianzouxiu/multi-datasource-transaction-demo.git
老师抽空帮我看看行吗?感激不尽呀~~~
写回答
1回答
-
首先,实在是抱歉,我前段时间一直出差,也比较忙,没有顾上看这个问题,我看到你问的几个多数据源的问题,我还给你回复了,结果你都自己解决了。还请见谅。
你试一下:
HashMap<String, Object> properties = new HashMap<String, Object>(); properties.put("hibernate.transaction.jta.platform", AtomikosJtaPlatform.class.getName()); properties.put("javax.persistence.transactionType", "JTA"); LocalContainerEntityManagerFactoryBean entityManager = new LocalContainerEntityManagerFactoryBean(); entityManager.setJpaPropertyMap(properties);如果还不行,那就是需要使用XADataSource,也就是`MysqlXADataSource`。
00
相似问题