Java JTA、Hibernate和atomikos多个XA数据源不在SpringBoot中维护事务

Java JTA、Hibernate和atomikos多个XA数据源不在SpringBoot中维护事务,java,spring,hibernate,spring-boot,atomikos,Java,Spring,Hibernate,Spring Boot,Atomikos,我有2个MySQLschema和相应的MysqlXADataSource配置如下- @Bean(name = "sourceDataSource") @Primary public DataSource dataSource() { MysqlXADataSource dataSource = new MysqlXADataSource(); dataSource.setPinGlobalTxToPhysicalConnection(true); dataSource.s

我有2个
MySQL
schema和相应的
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("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返回
    AtomikosDataSourceBean
    reference进行包装
  • 为AtomikosDataSourceBean分配唯一的名称
  • 服务方法应该是事务性的(transactionManager=“jtaTransactionManager”…),提供Spring
    jtaTransactionManager
  • JtaTransactionManager
    应与
    javax.transaction.UserTransaction
    一起引用,并具有
    com.atomikos.icatch.jta.J2eeUserTransaction
    实现
  • JtaTransactionManager
    应与
    com.atomikos.icatch.jta.UserTransactionManager
    实现一起引用
  • 问题中代码的其余部分是正确的

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

    什么不起作用?还有,为什么不直接使用Atomikos的开箱即用支持呢?您正在抛出一个选中的异常,回滚只发生在
    RuntimeException
    s上。您的
    jtaTransactionManager
    应该命名为
    transactionManager
    ,因为这是Spring期望的默认名称。如果不匹配,您需要明确告诉
    @EnableTransactionManagement
    使用哪个事务管理器。我认为使用了错误的事务管理器。默认情况下,
    @Transactional
    获得了您的UserTransactionManagerbean@M.Deinum@StanislavL我已经改变了一些返回atomikosDataSourceBean的数据源,并为它们添加了唯一的名称。我认为这就是问题所在。现在事务正在回滚,但需要验证。如我的评论中所述,将在出现任何问题时发布。添加了
    @Transactional(transactionManager=“jtaTransactionManager”…)
    @M.Deinum。。添加这些额外的代码解决了这个问题。谢谢你的帮助和支持。
    @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();
    }