Spring 涉及两个 DAO 的遗留代码交易

Spring transaction with legacy code involving two DAOs

我正在处理一些遗留代码,其中所有 Spring DAO 都使用 @Transactional 注释进行注释。 现在我有一个业务需求,我需要在我的服务层调用两个不同的 DAO 并在任何时候失败时回滚事务。

我如何在 Spring 5 中实现这一点而不从 DAO 中删除 @Transactional 注释并仍然在服务层中使用它们。我不认为下面的代码会起作用,因为每个 DAO 中的事务都是相互独立的。

非常感谢。

@Transactional
public FooDao {
}

@Transactional
public BarDao {
}


@Transactional
public TestServiceImple implements TestService {
  fooDao.action1();
  barDao.action2();
}

在@Transaction 中默认使用Propagation.REQUIRED,第二种方法将使用当前事务。 @Transactional(propagation=Propagation.REQUIRED),所以最后只会一笔交易。

如果您的总体目标是确保事务将回滚通过两个 dao 调用所做的更改,则在抛出未经检查的异常时,您应该能够从 dao 方法本身中删除 @Transactional,并将其保留在服务层。 Spring 中的事务可以是 class 或方法级别,因此在这种情况下,您可以只在调用两个 dao 方法的方法*上使用它(尽管,正如您指出的那样,您似乎想要将这些注释保留在 dao 层中?)。

事务的一般要点之一是在处理多个数据库更改时(对 dao(s) 的多次调用),因此在单个 dao 方法(或 dao 层)上进行事务注释并不是一个很好的设计一般来说)。

如果你有两个 daos 处理两个不同的数据源(不确定,你没有提到)那么,如果你 have/can 得到 spring 数据作为依赖,你可以利用ChainedTransactionManager (https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/transaction/ChainedTransactionManager.html)

  1. 默认propagation type for a @Transactional annotation is Propagation.REQUIRED.

Support a current transaction, create a new one if none exists.

  1. @Transactional 注释的默认 rollback 行为如下

By default, a transaction will be rolling back on RuntimeException and Error but not on checked exceptions (business exceptions).

这两个默认配置将确保 TestServiceImple 中的 fooDao.action1()barDao.action2() 在任何 RuntimeException/custom 回滚配置上使用相同的 txn 和回滚一起工作服务层,前提是这两个方法是从用 @Transactional 注释的同一个服务方法调用的。

示例

 @Transactional
 public TestServiceImple implements TestService {

     public void callDaoMethods(){
      fooDao.action1();
      barDao.action2();
     }

 }

public TestServiceImple implements TestService {

 @Transactional
 public void callDaoMethods(){
   fooDao.action1();
   barDao.action2();
 }
}