我知道当从同一个类中调用事务方法时,它不会在事务中运行。 Spring为事务方法创建一个代理,并将它们包装在try-catch块中,并在发生异常时回滚。请考虑以下情形:
@Transactional
public void saveAB(A a, B b)
{
saveA(a);
saveB(b);
}
@Transactional
public void saveA(A a)
{
dao.saveA(a);
}
@Transactional
public void saveB(B b)
{
dao.saveB(b);
}
假设从另一个对象调用saveAB并在saveB中发生异常,因此saveA成功完成但saveB没有成功。据我所知,即使saveA和saveB不是事务性的(因为它们是从同一个对象调用的),因为saveAB是事务性的,它仍然应该回滚。
我不明白为什么人们说自我调用打破了交易?只要调用者方法是事务性的,一切都不应该按预期工作吗?我在这里找不到任何东西?
答案 0 :(得分:9)
我不明白为什么人们说自我调用会中断 交易?
我从未听说过自我调用打破了交易。我所知道的是,自我调用不会启动新事务,您已经提到了原因。
来自Spring的交易管理规范的片段
注意在代理模式下(默认设置),只有外部方法调用 通过代理进入是截获的。这意味着 自调用,实际上是目标对象调用中的一个方法 目标对象的另一种方法,不会导致实际的 即使调用的方法被标记,运行时的事务也是如此 @Transactional。
如果从saveAB()中删除@Transaction注释,您会发现即使使用@Transactional注释,saveA()和saveB()也不会在事务下运行。但是,如果从类外部调用saveA()或saveB(),它将按预期在事务下运行。这就是为什么人们建议在自我调用时保持谨慎的原因。
public void saveAB(A a, B b)
{
saveA(a);
saveB(b);
}
@Transactional
public void saveA(A a)
{
dao.saveA(a);
}
@Transactional
public void saveB(B b)
{
dao.saveB(b);
}
在我看来,自我调用任何公共方法都是一个坏主意。
答案 1 :(得分:0)
如果你可以saveAB并且saveB抛出异常,你的事务就会回滚。
如果没有使用@Transactional注释saveAB,则Seld调用会破坏跨国行为。
所以你的例子中没有遗漏任何内容。