在一次采访中有人问我:我们如何在一次交易中管理两种交易/道方法。所需功能:
- 如果其中任何一个失败,我们都需要回滚这两种方法。
- 可以将这两种方法与单个事务分开附加调用。
- 管理应该在DAO层上,而不是在服务层上。
我认为:这个问题与春季交易管理有关。
在一次采访中有人问我:我们如何在一次交易中管理两种交易/道方法。所需功能:
我认为:这个问题与春季交易管理有关。
Answers:
首先,事务管理应该在服务层而不是DAO层进行,因为这会产生大量的性能开销(以适当的事务隔离级别和每种方法传播)。同样,工作单元的范围来自服务层而不是数据访问层:想象执行一个需要处理两个或多个DAO的业务流程。
无论如何,由于这是一次采访,所以我们按原样接受问题。从我的角度来看,您将@Transactional
在两种方法中都使用注释(或XML配置),并在有价交易中使用REQUIRED
。这样,当调用这些方法中的任何一个并且如果不存在先前的事务时,将创建一个新的事务:
@Transactional
class MyDAO {
@Transactional(propagation = REQUIRED)
public void foo() {
}
@Transactional(propagation = REQUIRED)
public void bar() {
}
}
@Transactional(propagation = REQUIRED)
在DAO层中进行传播并@Transactional
在服务层中添加方法,但是如果@Transactional
仅放置服务层而不是放置在DAO层中,有什么区别?
propagation = REQUIRED
是事务性注释传播的默认值,因此无需编写它。
在我的答案中忽略弹簧和框架.....只是使用函数参数的基本思想。我确信这个概念可以在[在这里插入框架]中使用。
您将需要在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(); }
}
Tran t
同时使用这两种方法作为参数。你能提供一些解释吗?
有两种方法可能同时在同一事务中运行同时独立工作,因此我们需要使用Propagation-Required。如果事务必须在同一事务中运行,则它将使用第一个事务,否则,如果独立调用,则会创建一个新事务。如果我错了,请纠正我。
foo()
并bar()
共享同一笔交易,如果1失败,另外1也会回滚?您能提供一些澄清吗?