如何在单个事务中管理2种DAO方法?


12

在一次采访中有人问我:我们如何在一次交易中管理两种交易/道方法。所需功能:

  1. 如果其中任何一个失败,我们都需要回滚这两种方法。
  2. 可以将这两种方法与单个事务分开附加调用。
  3. 管理应该在DAO层上,而不是在服务层上。

我认为:这个问题与春季交易管理有关。

Answers:


12

首先,事务管理应该在服务层而不是DAO层进行,因为这会产生大量的性能开销(以适当的事务隔离级别和每种方法传播)。同样,工作单元的范围来自服务层而不是数据访问层:想象执行一个需要处理两个或多个DAO的业务流程。

互联网上的许多讨论都指向这里这里这里的方向。

无论如何,由于这是一次采访,所以我们按原样接受问题。从我的角度来看,您将@Transactional在两种方法中都使用注释(或XML配置),并在有价交易中使用REQUIRED。这样,当调用这些方法中的任何一个并且如果不存在先前的事务时,将创建一个新的事务:

@Transactional
class MyDAO {

   @Transactional(propagation = REQUIRED)
   public void foo() {
   }

   @Transactional(propagation = REQUIRED)
   public void bar() {
   }

}

这是否意味着foo()bar()共享同一笔交易,如果1失败,另外1也会回滚?您能提供一些澄清吗?
Satish Pandey 2012年

好吧,每个方法都声明自己的工作单元:tx将在每个方法的末尾提交,如果它们中的任何一个抛出异常,它将被回滚。
阿隆索·多明格斯

因此我们需要@Transactional(propagation = REQUIRED)在DAO层中进行传播并@Transactional在服务层中添加方法,但是如果@Transactional仅放置服务层而不是放置在DAO层中,有什么区别?
atish shimpi

propagation = REQUIRED是事务性注释传播的默认值,因此无需编写它。
丹尼尔·希格拉斯

2

在我的答案中忽略弹簧和框架.....只是使用函数参数的基本思想。我确信这个概念可以在[在这里插入框架]中使用。

您将需要在2种DAO方法之外处理提交/回滚。这两种方法需要将事务/连接作为输入。

伪代码:

bool method1(Tran t) { /* stuff */}
bool method2(Tran t) { /* stuff */ }

callingMethod() {
     Tran t = null;
     try {
         t = new Conn().open().startTran();
         if(method1(t) && method2(t))
             t.commit();
         else
             t.rollBaack();
     }
     catch(ex) {  t.rollBack();  }
     finally {  t.closeConn();  }
}

1个问题:为什么我们要Tran t同时使用这两种方法作为参数。你能提供一些解释吗?
Satish Pandey 2012年

@Satish,因为在问题(项目1和项目2)中,DAO方法需要具有灵活性,可以独立或依赖地进行调用。如果您使用本地作用域事务在method1内提交,则在method2中出现问题时将无法回滚,因为在调用method2之前已经提交了method1。
mike30'9

0

有两种方法可能同时在同一事务中运行同时独立工作,因此我们需要使用Propagation-Required。如果事务必须在同一事务中运行,则它将使用第一个事务,否则,如果独立调用,则会创建一个新事务。如果我错了,请纠正我。


你能举个例子吗?
杰伊·埃尔斯顿
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.