我知道当从同一类内部调用事务方法时,它不会在事务中运行。 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没有成功。据我所知,即使saveAsaveB不是事务性的(因为它们是从同一对象调用的),因为saveAB是事务性的,所以它仍应回滚。

我不明白的是,为什么人们说自我调用会破坏交易?只要调用方方法是事务性的,所有的事情就不应该按预期运行吗?我在这里想念什么吗?

最佳答案



我从未听说过自调用会中断事务。我所知道的是,自调用不会启动新事务,您已经提到了原因。

Spring的事务管理规范中的



如果从@Transaction中删除saveAB()批注,则会观察到saveA()saveB()方法即使在事务中使用@Transactional进行注释也不会在事务下运行。但是,如果从类外部调用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);
}

我认为,自行调用任何公共(public)方法都是一个坏主意。

07-24 22:12