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();
}

并且有相应的子服务 类 transformProducttransformServicetransformResources 这些 类 正在使用 sessionFactory 实现的 dao 类。我没有提到提交或回滚。一切都应该是跨国的。但不知何故它不起作用

好的..代码中有错误 -

  1. XA 数据源必须用 AtomikosDataSourceBean ans 包裹 return AtomikosDataSourceBean 引用。
  2. AtomikosDataSourceBean 分配唯一名称。
  3. 应制定服务方法@Transactional(transactionManager = "jtaTransactionManager" ...),提供SpringJtaTransactionManager
  4. JtaTransactionManager 应与具有 com.atomikos.icatch.jta.J2eeUserTransaction 实施的 javax.transaction.UserTransaction 一起引用。
  5. JtaTransactionManager 应在 com.atomikos.icatch.jta.UserTransactionManager 实施中引用。
  6. 问题中其余代码正确。

这是对 Atomikos 的直接开箱即用支持。