Spring @Transactional注解:自我调用 [英] Spring @Transactional Annotation : Self Invocation

查看:993
本文介绍了Spring @Transactional注解:自我调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道何时从同一个类中调用一个事务方法,它不会在事务中运行。 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);





$ b假设saveAB被另一个对象调用,并且在saveB中发生了一个异常,所以saveA成功完成但saveB没有。据我所知,即使saveA和saveB不是事务性的(因为它们是从同一个对象中调用的),因为saveAB是事务性的,它仍然应该回滚。

我不明白为什么人们说自我调用会破坏事务?只要调用方法是事务性的,不应该像所期望的那样工作?

解决方案


我不明白的是为什么人们说自我调用破坏了
事务吗?

我从来没有听说过自我调用破坏了事务。我所知道的是,自我调用不会启动一个新的事务,并且您已经提到了原因。

Spring的事务管理规范片段
$ b


注意在代理模式下(这是默认模式),只有通过代理进入的外部方法调用
被拦截。这意味着
自我调用实际上是调用目标对象中另一个方法的目标对象中的一种方法,即使调用的方法在运行时也不会导致实际的
事务标记为
@Transactional。






如果删除@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);
}

在我看来,自行调用任何公共方法是一个坏主意。 / p>

I know when a transactional method is called from inside the same class it wouldn't be run in a transaction. Spring creates a proxy for transactional methods and wraps them in a try-catch block and rolls back if an exception occurs. Consider the following scenario:

@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);
}

Assume saveAB is called from another object and an exception occurred in saveB, so saveA completed successfully but saveB did not. To my knowledge even though saveA and saveB are not transactional (because they are called from the same object), since saveAB is transactional it should still roll back.

What I don't understand is why do people say self invocation breaks transaction? As long as the caller method is transactional shouldn't everything work as expected? Is there anything I'm missing here?

解决方案

What I don't understand is why do people say self invocation breaks transaction?

I never heard that self-invocation breaks transaction. All I know is that self-invocation will not start a new transaction and you already mentioned the reason why.

Snippet from Spring's Transaction Management Specification

Note In proxy mode (which is the default), only external method calls coming in through the proxy are intercepted. This means that self-invocation, in effect, a method within the target object calling another method of the target object, will not lead to an actual transaction at runtime even if the invoked method is marked with @Transactional.


If you remove @Transaction annotation from saveAB(), you would observe that method saveA() and saveB() would not run under transaction even though it is annotated with @Transactional. However, if you call saveA() or saveB() from outside the class, it will run under transaction as expected. That is the reason why people advice to be cautious with self-invocation.

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);
}

In my view, self-invoking any public method is a bad idea.

这篇关于Spring @Transactional注解:自我调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆