JTA,Hibernate with atomikos 多个 XA 数据源不在 SpringBoot 中维护事务
JTA, Hibernate with atomikos Multiple XA Datasources not maintaing transaction in SpringBoot
我有 2 个 MySQL
模式和相应的 MysqlXADataSource
配置如下 -
@Bean(name = "sourceDataSource")
@Primary
public DataSource dataSource() {
MysqlXADataSource dataSource = new MysqlXADataSource();
dataSource.setPinGlobalTxToPhysicalConnection(true);
dataSource.setUrl(DB_URL);
dataSource.setUser(DB_USERNAME);
dataSource.setPassword(DB_PASSWORD);
AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
atomikosDataSourceBean.setUniqueResourceName("SourceDB");
atomikosDataSourceBean.setXaDataSource(dataSource);
/*DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(DB_DRIVER);
dataSource.setUrl(DB_URL);
dataSource.setUsername(DB_USERNAME);
dataSource.setPassword(DB_PASSWORD);*/
System.out.println("Creatign Source data source.");
return atomikosDataSourceBean;
}
@Bean(name = "sourceSessionFactory")
public LocalSessionFactoryBean sessionFactory(@Qualifier("jtaTransactionManager") JtaTransactionManager jts) {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource());
sessionFactoryBean.setPackagesToScan(ENTITYMANAGER_PACKAGES_TO_SCAN);
Properties hibernateProperties = new Properties();
hibernateProperties.put("hibernate.dialect", HIBERNATE_DIALECT);
hibernateProperties.put("hibernate.show_sql", HIBERNATE_SHOW_SQL);
hibernateProperties.put("hibernate.hbm2ddl.auto", HIBERNATE_HBM2DDL_AUTO);
hibernateProperties.put("hibernate.transaction.factory_class", "org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory");
hibernateProperties.put("hibernate.transaction.coordinator_class", "jta");
hibernateProperties.put("hibernate.transaction.jta.platform", "com.atomikos.icatch.jta.hibernate4.AtomikosPlatform");
//hibernateProperties.put("hibernate.transaction.jta.platform", AtomikosJtaPlatform.class.getName());
sessionFactoryBean.setJtaTransactionManager(jts);
sessionFactoryBean.setHibernateProperties(hibernateProperties);
System.out.println("Creatign Source Session Factory.");
return sessionFactoryBean;
}
和
@Bean(name="destinationDataSource")
public DataSource dataSource() {
MysqlXADataSource dataSource = new MysqlXADataSource();
dataSource.setPinGlobalTxToPhysicalConnection(true);
dataSource.setUrl(DB_URL);
dataSource.setUser(DB_USERNAME);
dataSource.setPassword(DB_PASSWORD);
AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
atomikosDataSourceBean.setUniqueResourceName("DestinationDB");
atomikosDataSourceBean.setXaDataSource(dataSource);
/*DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(DB_DRIVER);
dataSource.setUrl(DB_URL);
dataSource.setUsername(DB_USERNAME);
dataSource.setPassword(DB_PASSWORD);
System.out.println("Creatign Destination Data Source.");*/
return atomikosDataSourceBean;
}
@Bean(name="destinationSessionFactory")
public LocalSessionFactoryBean sessionFactory(@Qualifier("jtaTransactionManager") JtaTransactionManager jts) {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource());
sessionFactoryBean.setPackagesToScan(ENTITYMANAGER_PACKAGES_TO_SCAN);
Properties hibernateProperties = new Properties();
hibernateProperties.put("hibernate.dialect", HIBERNATE_DIALECT);
hibernateProperties.put("hibernate.show_sql", HIBERNATE_SHOW_SQL);
hibernateProperties.put("hibernate.hbm2ddl.auto", HIBERNATE_HBM2DDL_AUTO);
hibernateProperties.put("hibernate.transaction.factory_class", "org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory");
hibernateProperties.put("hibernate.transaction.coordinator_class", "jta");
hibernateProperties.put("hibernate.transaction.jta.platform", "com.atomikos.icatch.jta.hibernate4.AtomikosPlatform");
sessionFactoryBean.setJtaTransactionManager(jts);
sessionFactoryBean.setHibernateProperties(hibernateProperties);
System.out.println("Creatign Destination Session Factoy.");
return sessionFactoryBean;
}
事务配置
@Bean("transactionManager")
public UserTransactionManager transactionManager(){
UserTransactionManager userTransactionManager = new UserTransactionManager();
return userTransactionManager;
}
@Bean("userTransaction")
public UserTransaction userTransaction(){
J2eeUserTransaction userTransaction = new J2eeUserTransaction();
return userTransaction;
}
@Bean("jtaTransactionManager")
public JtaTransactionManager jtaTransactionManager(@Qualifier("transactionManager") UserTransactionManager userTransactionManager, @Qualifier("userTransaction") UserTransaction userTransaction) {
JtaTransactionManager transactionManager = new JtaTransactionManager();
transactionManager.setTransactionManager(userTransactionManager);
transactionManager.setUserTransaction(userTransaction);
//transactionManager.setSessionFactory(sessionFactory().getObject());
System.out.println("Creatign JTA Transaction Manager.");
return transactionManager;
}
服务...
@Transactional(transactionManager = "jtaTransactionManager", propagation=Propagation.REQUIRES_NEW, rollbackFor=Exception.class, timeout=500000)
public void transform() throws JobExecutionException{
System.out.println("START == Starting Trandformation ... ");
//Clean Up
transformProduct.cleanUp();
transformService.cleanUp();
transformResources.cleanUp();
transformResources.transform();
transformService.transform();
transformProduct.transform();
LOG.info("END == Starting Transformation ... ");
throw new JobExecutionException();
}
并且有相应的子服务 类 transformProduct
、transformService
和 transformResources
这些 类 正在使用 sessionFactory
实现的 dao 类。我没有提到提交或回滚。一切都应该是跨国的。但不知何故它不起作用
好的..代码中有错误 -
- XA 数据源必须用
AtomikosDataSourceBean
ans 包裹 return AtomikosDataSourceBean
引用。
- 为
AtomikosDataSourceBean
分配唯一名称。
- 应制定服务方法
@Transactional(transactionManager = "jtaTransactionManager" ...)
,提供SpringJtaTransactionManager
。
JtaTransactionManager
应与具有 com.atomikos.icatch.jta.J2eeUserTransaction
实施的 javax.transaction.UserTransaction
一起引用。
JtaTransactionManager
应在 com.atomikos.icatch.jta.UserTransactionManager
实施中引用。
- 问题中其余代码正确。
这是对 Atomikos 的直接开箱即用支持。
我有 2 个 MySQL
模式和相应的 MysqlXADataSource
配置如下 -
@Bean(name = "sourceDataSource")
@Primary
public DataSource dataSource() {
MysqlXADataSource dataSource = new MysqlXADataSource();
dataSource.setPinGlobalTxToPhysicalConnection(true);
dataSource.setUrl(DB_URL);
dataSource.setUser(DB_USERNAME);
dataSource.setPassword(DB_PASSWORD);
AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
atomikosDataSourceBean.setUniqueResourceName("SourceDB");
atomikosDataSourceBean.setXaDataSource(dataSource);
/*DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(DB_DRIVER);
dataSource.setUrl(DB_URL);
dataSource.setUsername(DB_USERNAME);
dataSource.setPassword(DB_PASSWORD);*/
System.out.println("Creatign Source data source.");
return atomikosDataSourceBean;
}
@Bean(name = "sourceSessionFactory")
public LocalSessionFactoryBean sessionFactory(@Qualifier("jtaTransactionManager") JtaTransactionManager jts) {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource());
sessionFactoryBean.setPackagesToScan(ENTITYMANAGER_PACKAGES_TO_SCAN);
Properties hibernateProperties = new Properties();
hibernateProperties.put("hibernate.dialect", HIBERNATE_DIALECT);
hibernateProperties.put("hibernate.show_sql", HIBERNATE_SHOW_SQL);
hibernateProperties.put("hibernate.hbm2ddl.auto", HIBERNATE_HBM2DDL_AUTO);
hibernateProperties.put("hibernate.transaction.factory_class", "org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory");
hibernateProperties.put("hibernate.transaction.coordinator_class", "jta");
hibernateProperties.put("hibernate.transaction.jta.platform", "com.atomikos.icatch.jta.hibernate4.AtomikosPlatform");
//hibernateProperties.put("hibernate.transaction.jta.platform", AtomikosJtaPlatform.class.getName());
sessionFactoryBean.setJtaTransactionManager(jts);
sessionFactoryBean.setHibernateProperties(hibernateProperties);
System.out.println("Creatign Source Session Factory.");
return sessionFactoryBean;
}
和
@Bean(name="destinationDataSource")
public DataSource dataSource() {
MysqlXADataSource dataSource = new MysqlXADataSource();
dataSource.setPinGlobalTxToPhysicalConnection(true);
dataSource.setUrl(DB_URL);
dataSource.setUser(DB_USERNAME);
dataSource.setPassword(DB_PASSWORD);
AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
atomikosDataSourceBean.setUniqueResourceName("DestinationDB");
atomikosDataSourceBean.setXaDataSource(dataSource);
/*DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(DB_DRIVER);
dataSource.setUrl(DB_URL);
dataSource.setUsername(DB_USERNAME);
dataSource.setPassword(DB_PASSWORD);
System.out.println("Creatign Destination Data Source.");*/
return atomikosDataSourceBean;
}
@Bean(name="destinationSessionFactory")
public LocalSessionFactoryBean sessionFactory(@Qualifier("jtaTransactionManager") JtaTransactionManager jts) {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource());
sessionFactoryBean.setPackagesToScan(ENTITYMANAGER_PACKAGES_TO_SCAN);
Properties hibernateProperties = new Properties();
hibernateProperties.put("hibernate.dialect", HIBERNATE_DIALECT);
hibernateProperties.put("hibernate.show_sql", HIBERNATE_SHOW_SQL);
hibernateProperties.put("hibernate.hbm2ddl.auto", HIBERNATE_HBM2DDL_AUTO);
hibernateProperties.put("hibernate.transaction.factory_class", "org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory");
hibernateProperties.put("hibernate.transaction.coordinator_class", "jta");
hibernateProperties.put("hibernate.transaction.jta.platform", "com.atomikos.icatch.jta.hibernate4.AtomikosPlatform");
sessionFactoryBean.setJtaTransactionManager(jts);
sessionFactoryBean.setHibernateProperties(hibernateProperties);
System.out.println("Creatign Destination Session Factoy.");
return sessionFactoryBean;
}
事务配置
@Bean("transactionManager")
public UserTransactionManager transactionManager(){
UserTransactionManager userTransactionManager = new UserTransactionManager();
return userTransactionManager;
}
@Bean("userTransaction")
public UserTransaction userTransaction(){
J2eeUserTransaction userTransaction = new J2eeUserTransaction();
return userTransaction;
}
@Bean("jtaTransactionManager")
public JtaTransactionManager jtaTransactionManager(@Qualifier("transactionManager") UserTransactionManager userTransactionManager, @Qualifier("userTransaction") UserTransaction userTransaction) {
JtaTransactionManager transactionManager = new JtaTransactionManager();
transactionManager.setTransactionManager(userTransactionManager);
transactionManager.setUserTransaction(userTransaction);
//transactionManager.setSessionFactory(sessionFactory().getObject());
System.out.println("Creatign JTA Transaction Manager.");
return transactionManager;
}
服务...
@Transactional(transactionManager = "jtaTransactionManager", propagation=Propagation.REQUIRES_NEW, rollbackFor=Exception.class, timeout=500000)
public void transform() throws JobExecutionException{
System.out.println("START == Starting Trandformation ... ");
//Clean Up
transformProduct.cleanUp();
transformService.cleanUp();
transformResources.cleanUp();
transformResources.transform();
transformService.transform();
transformProduct.transform();
LOG.info("END == Starting Transformation ... ");
throw new JobExecutionException();
}
并且有相应的子服务 类 transformProduct
、transformService
和 transformResources
这些 类 正在使用 sessionFactory
实现的 dao 类。我没有提到提交或回滚。一切都应该是跨国的。但不知何故它不起作用
好的..代码中有错误 -
- XA 数据源必须用
AtomikosDataSourceBean
ans 包裹 returnAtomikosDataSourceBean
引用。 - 为
AtomikosDataSourceBean
分配唯一名称。 - 应制定服务方法
@Transactional(transactionManager = "jtaTransactionManager" ...)
,提供SpringJtaTransactionManager
。 JtaTransactionManager
应与具有com.atomikos.icatch.jta.J2eeUserTransaction
实施的javax.transaction.UserTransaction
一起引用。JtaTransactionManager
应在com.atomikos.icatch.jta.UserTransactionManager
实施中引用。- 问题中其余代码正确。
这是对 Atomikos 的直接开箱即用支持。