带有涉及两个 DAO 的遗留代码的 Spring 事务
Posted
技术标签:
【中文标题】带有涉及两个 DAO 的遗留代码的 Spring 事务【英文标题】:Spring transaction with legacy code involving two DAOs 【发布时间】:2020-05-18 17:36:56 【问题描述】:我正在使用一些遗留代码,其中所有 Spring DAO 都使用 @Transactional 注释进行了注释。 现在我有一个业务需求,我需要在我的服务层中调用两个不同的 DAO,并在事务在任何时候失败时回滚事务。
如何在 Spring 5 中实现这一点,而无需从 DAO 中删除 @Transactional 注释并仍然从服务层使用它们。我认为下面的代码不会起作用,因为每个 DAO 中的事务将彼此独立。
非常感谢。
@Transactional
public FooDao
@Transactional
public BarDao
@Transactional
public TestServiceImple implements TestService
fooDao.action1();
barDao.action2();
【问题讨论】:
【参考方案1】:-
@Transactional 注释的默认propagation 类型是Propagation.REQUIRED。
支持当前事务,如果不存在则创建一个新事务。
-
@Transactional 注释的默认rollback 行为如下
默认情况下,事务将在 RuntimeException 和 错误但不在检查异常(业务异常)上。
这两个默认配置将确保 TestServiceImple
中的 fooDao.action1()
和 barDao.action2()
使用相同的 txn 并在服务层的任何 RuntimeException/自定义回滚配置上一起回滚,前提是这两个方法是从使用 @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();
【讨论】:
这个也很有用:***.com/questions/5684473/…【参考方案2】:@Transaction 中默认使用 Propagation.REQUIRED,第二种方法将使用当前事务。 @Transactional(propagation=Propagation.REQUIRED),所以最终它只会进行一笔交易。
【讨论】:
【参考方案3】:如果您的总体目标是确保事务将回滚通过两个 dao 调用所做的更改,那么当引发未经检查的异常时,您应该能够从 dao 方法本身中删除 @Transactional,并将其保留在服务层中. Spring 中的事务可以是类或方法级别,因此在这种情况下,您可以只在调用两个 dao 方法的方法*上使用它(尽管,正如您所指出的,您似乎希望将这些注释保留在 dao 层中?) .
事务的一般要点之一是在处理多个数据库更改(对 dao 的多次调用)时,因此在单个 dao 方法(或一般的 dao 层)上具有事务注释并不是一个很好的设计)。
如果你是两个 daos 处理两个不同的数据源(不确定,你没有提到)那么,如果你有/可以获取 spring 数据作为依赖项,你可以利用 ChainedTransactionManager (https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/transaction/ChainedTransactionManager.html)
【讨论】:
以上是关于带有涉及两个 DAO 的遗留代码的 Spring 事务的主要内容,如果未能解决你的问题,请参考以下文章
注入 DAO 的 @Transactional 的 Spring WS 拦截器不起作用
Spring 3,带有通用 DAO 的 Hibernate 4 AutoWired sessionFactory