【问题标题】:@Transactional saveAll not working for a table in 2nd data source Spring JPA@Transactional saveAll 不适用于第二个数据源 Spring JPA 中的表
【发布时间】:2019-07-21 12:02:49
【问题描述】:

我有 2 个数据源,ds1,ds2。在@Transactional 的单一服务中,我必须从两个表中获取值并更新它们。

示例 sn-p

    @Service
    public class MyService {
    @Autowired
    ds1Repository ds1Repository; // from data source 1 (DB Name - DB1) MYSQL
    @Autowired
    ds2Repository ds2Repository; // from data source 2 (DB Name - DB2) MYSQL

    @Transactional (javax.Transactional)
    public void processUpdates() {
        // Able to get the result set from both the data sources
        List<Data1> ds1Data = ds1Repository.findAll();
        List<Data2> ds2Data = ds1Repository.findAll();

        // modified the collections ds1Data & ds2Data

        // This is getting updated
        ds1Repository.saveAll(ds1Data);

        // This update is not heppening and no exception thrown
        ds2Repository.saveAll(ds2Data);
    }
}

我已经尝试了以下 wys:

  1. 我已经配置了两个工作正常的数据源,能够从两个数据库中读取数据
  2. 搜索后,尝试了 ChainedTransactionManager,通过为两个数据源定义自定义事务管理器名称并在服务之上使用 @Transactional(value="chainedTransactionManager")。还是不行。

谁能帮我解决一下代码的问题?为什么只有数据源 2 上的数据没有被持久化?

【问题讨论】:

  • 你能用ChainedTransactionManager粘贴你的尝试吗?
  • public class MultiDataSourceTransactionManager { @Bean(name = "chainedTransactionManager") public ChainedTransactionManager transactionManager(@Qualifier("transactionManager") PlatformTransactionManager ds1, @Qualifier("tm2") PlatformTransactionManager ds2) { return new ChainedTransactionManager(ds1, ds2); } }

标签: java hibernate spring-data-jpa spring-data


【解决方案1】:
  • 您有 2 个数据源,这意味着您将有 2 个 TransactionManager bean
  • 现在,当您使用 @Transactional 而不指定名称时,它会 使用默认的 TransactionManager
  • 这意味着,只有默认事务被提交一次 processUpdate() 完成

建议

  • 我不知道你是否有分布式事务管理的需求,如果没有,那么只需在 saveAll() 上使用独立的 @Transactional 并使用适当的 TransactionManager 名称

【讨论】:

    【解决方案2】:

    正如 Arjun 建议的那样,您可以将 saveAll 上的事务与适当的事务管理器一起使用。

    或者你可以像这样定义一个分布式事务管理器(假设你有两个事务管理器的 bean):

    @Configuration
    public class ChainedTransactionManagerConfig
    {
        /**
         * combined TM
         */
        public static final String TRANSACTION_MANAGER = "chainedTransactionManager";
    
        /**
         * 
         * @param oneTransactionManager oneTransactionManager
         * @param twoTransactionManager twoTransactionManager
         * @return combined TM
         */
        @Bean(name = TRANSACTION_MANAGER)
        public ChainedTransactionManager transactionManager(
                // Bean name of the first one
                @Qualifier("firstTransactionManager") PlatformTransactionManager oneTransactionManager,
                // Bean name of the second one
                @Qualifier("secondTransactionManager") PlatformTransactionManager twoTransactionManager)
        {
            return new ChainedTransactionManager(oneTransactionManager, twoTransactionManager);
        }
    }
    

    然后你可以像这样在你的方法上使用它:

    import org.springframework.transaction.annotation.Transactional;
    
    @Transactional(transactionManager = ChainedTransactionManagerConfig.TRANSACTION_MANAGER)
    

    另外请使用 Spring 的事务性注解 (org.springframework.transaction.annotation)

    【讨论】:

      猜你喜欢
      • 2015-11-06
      • 2020-10-25
      • 2010-12-30
      • 1970-01-01
      • 2015-12-11
      • 1970-01-01
      • 2011-01-22
      • 1970-01-01
      • 2021-11-28
      相关资源
      最近更新 更多