Spring @Transactional具有跨多个数据源的事务

Do *_*ill 5 spring hibernate transactions transactionmanager spring-data-jpa

作为一个事务的一部分,我必须更新两个数据源。那是 -

  1. 我在DB1中进行了更新。
  2. 然后,我在DB2中进行另一个更新。

如果DB2中的更新失败,我想回滚DB1和DB2来回滚。可以使用@Transactional完成此操作吗?

这是一个示例代码-

@Transactional(value="db01TransactionManager")
public void updateDb01() {
    Entity01 entity01 = repository01.findOne(1234);
    entity01.setName("Name");
    repository01.save(entity01);

    //Calling method to update DB02
    updateDb02();
}

@Transactional(value="db02TransactionManager")
public void updateDb02() {
    Entity02 entity02 = repository02.findOne(1234);
    entity02.setName("Name");
    repository02.save(entity02);

    //Added this to force a roll back for testing
    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,updateDb02中的setRollbackOnly()仅回滚Db01事务。

kol*_*ant 14

我已经解决使用ChainedTransactionManager这个问题- http://docs.spring.io/spring-data/commons/docs/1.6.2.RELEASE/api/org/springframework/data/transaction/ChainedTransactionManager.html

Spring Boot配置:

    @Bean(name = "chainedTransactionManager")
    public ChainedTransactionManager transactionManager(@Qualifier("primaryDs") PlatformTransactionManager ds1,
                                                    @Qualifier("secondaryDs") PlatformTransactionManager ds2) {
         return new ChainedTransactionManager(ds1, ds2);
    }
Run Code Online (Sandbox Code Playgroud)

然后可以按以下方式使用它:

@Transactional(value="chainedTransactionManager")
public void updateDb01() {
    Entity01 entity01 = repository01.findOne(1234);
    entity01.setName("Name");
    repository01.save(entity01);

    //Calling method to update DB02
    updateDb02();
}

public void updateDb02() {
    Entity02 entity02 = repository02.findOne(1234);
    entity02.setName("Name");
    repository02.save(entity02);

    //Added this to force a roll back for testing
    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,[ChainedTransactionManager](https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/transaction/ChainedTransactionManager.html) 已被 **弃用**,因为它的意外行为。请参阅此[票证](https://github.com/spring-projects/spring-data-commons/issues/2232)以获取更多信息。 (11认同)
  • 这是我写的一篇文章,说明如何使用一些更详细的代码示例来设置链式事务管理器。这可能有助于解释所有组件如何协同工作以产生此结果:https://metamorphant.de/blog/posts/2021-03-21-distributed-transactions-across-multiple-dbs-chainedtransactionmanager/ (3认同)
  • 对于未来的自己和其他人:如果您希望“@Transactional”默认使用“ChainedTransactionManager”,请在“ChainedTransactionManager” bean 上添加“@Primary”。 (2认同)

Do *_*ill 1

弄清楚了。

这些方法必须位于不同的 bean 中才能使用不同的事务管理器。