Spring事务与涉及两个DAO的遗留代码
在使用Spring事务处理与涉及两个DAO的旧代码时,出现了以下问题:
- 目标是确保当抛出未经检查的异常时,事务将回滚通过两个dao调用所做的更改。
- 希望保留dao层中的事务注解。
解决方法:
- 可以在服务层中保留事务注解,并从dao方法中删除它们。Spring的事务可以是类级别或方法级别的,因此可以只在调用两个dao方法的方法上使用事务注解。
- 如果两个dao处理两个不同的数据源,可以使用Spring数据的ChainedTransactionManager来处理多个数据源的事务。具体可以参考https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/transaction/ChainedTransactionManager.html。
问题的出现原因:由于在第二个方法中使用了默认的Propagation.REQUIRED传播行为,因此它会使用当前的事务,最终只会有一个事务。
解决方法:
为了解决这个问题,可以考虑将第二个方法的传播行为设置为Propagation.REQUIRES_NEW,这样就会创建一个新的事务。这样在第一个方法的事务提交之前,第二个方法的事务就会独立于第一个方法的事务进行提交。
代码示例:
@Transactional(propagation = Propagation.REQUIRED) public void method1() { // 执行业务逻辑 dao1.save(data1); method2(); } @Transactional(propagation = Propagation.REQUIRES_NEW) public void method2() { // 执行业务逻辑 dao2.save(data2); }
在上面的代码示例中,我们在第一个方法method1()上添加了@Transactional注解,并设置了传播行为为Propagation.REQUIRED。在第二个方法method2()上也添加了@Transactional注解,并设置了传播行为为Propagation.REQUIRES_NEW。
这样,当method1()方法执行时,会创建一个事务,并在调用method2()方法时继续使用该事务。而method2()方法在执行时,会创建一个新的事务,与method1()方法的事务相互独立。
通过这种方式,我们可以解决在使用两个DAO对象时,需要分别使用不同的事务的问题。
Spring事务与涉及两个DAO的旧代码(Spring transaction with legacy code involving two DAOs)
在这篇文章中,我们将讨论Spring事务管理中的一个问题,即涉及两个DAO(数据访问对象)的旧代码。我们将探讨该问题的原因以及可能的解决方法。
问题的原因是两个默认配置。首先,@Transactional注解的默认传播类型是Propagation.REQUIRED。这意味着如果当前存在事务,则支持该事务;如果不存在事务,则创建一个新的事务。其次,默认情况下,@Transactional注解的默认回滚行为是只在RuntimeException和Error发生时回滚,而不在检查异常(业务异常)发生时回滚。
这两个默认配置确保在同一个service方法中通过相同的事务处理fooDao.action1()和barDao.action2()方法,并且在服务层中出现RuntimeException或自定义回滚配置时进行回滚。
以下是一个示例代码:
public class TestServiceImpl implements TestService { public void callDaoMethods() { fooDao.action1(); barDao.action2(); } }
这个问题的解决方法是将两个DAO方法的调用放在一个新的事务中。为此,我们可以在service方法上添加@Transactional注解,并在调用DAO方法之前使用@Transactional注解的propagation属性将传播类型设置为Propagation.REQUIRES_NEW。这将在每个DAO方法调用之前创建一个新的事务,并确保它们在任何异常发生时都可以回滚。
下面是修改后的代码:
public class TestServiceImpl implements TestService { @Transactional(propagation = Propagation.REQUIRES_NEW) public void callDaoMethods() { fooDao.action1(); barDao.action2(); } }
通过这种方式,我们可以解决涉及两个DAO的旧代码中的事务管理问题。
参考链接:
- 默认传播类型:https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/annotation/Transactional.html#propagation--
- 默认回滚行为:https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/annotation/Transactional.html#rollbackFor--