理解 Spring 事务 - 当一个事务方法调用另一个事务方法时会发生什么? [英] Understanding Spring transactions - What happens when a transactional method calls another transactional method?

查看:31
本文介绍了理解 Spring 事务 - 当一个事务方法调用另一个事务方法时会发生什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

只是为了了解 Spring 事务的工作原理,我想知道在以下情况下会发生什么,其中一个标记为 @Transactional 的方法调用另一个标记为 @Transactional 的方法.

Just to understand the workings of Spring transactions I want to know what happens in the following case where one method marked as @Transactional calls another method marked as @Transactional.

假设配置使用所有默认设置.

Assume a the configuration uses all default settings.

@Service("myService")
@Transactional
public MyService{
   public void myServiceMethod(){
      myDAO.getSomeDBObjects();
   }
}

@Repository("myDAO")
@Transactional
public MyDAOWithUsesBeyondMyService{
   public void getSomeDBObjects(){...}
}

现在,如果我输入 MyService.myServiceMethod(),它显然会启动一个事务.然后,在钻入 myDAO.getSomeDBObjects() 时会发生什么?一个交易已经存在的事实会导致没有新的交易诞生,还是我在这里创建了两个交易?

Now if I were to enter MyService.myServiceMethod() it would clearly start a transaction. Then, upon drilling into myDAO.getSomeDBObjects() what would happen? Would the fact that a transaction already exist cause no new transaction to be born, or am I creating two transactions here?

关于传播的文档(下面引用)似乎涵盖了这一点,但我想验证一下我的理解,我的处女脑一下子理解了一点.

The documentation (quoted below) on Propagation seems to cover this, but I'd like to verify my understanding, it was a little much for my virgin brain to comprehend all at once.

传播:通常,所有代码在事务范围内执行将在该事务中运行.然而,您可以选择指定行为在一个事件事务方法在什么时候执行事务上下文已经存在.例如,代码可以继续运行在现有交易中(常见情况);或现有的可以暂停交易并创建一个新的交易创建.Spring 提供所有交易传播选项熟悉 EJB CMT.阅读事务的语义在 Spring 中传播,请参阅部分10.5.7,交易传播".

Propagation: Typically, all code executed within a transaction scope will run in that transaction. However, you have the option of specifying the behavior in the event that a transactional method is executed when a transaction context already exists. For example, code can continue running in the existing transaction (the common case); or the existing transaction can be suspended and a new transaction created. Spring offers all of the transaction propagation options familiar from EJB CMT. To read about the semantics of transaction propagation in Spring, see Section 10.5.7, "Transaction propagation".

推荐答案

两个答案:

a) 不要这样做.在服务层或 dao 层使用 @Transactional,但不能同时使用(服务层是通常的选择,因为您可能希望每个服务方法一个事务)

a) don't do it. Use @Transactional in the service layer or the dao layer, but not both (the service layer is the usual choice, as you probably want one transaction per service method)

b) 如果你这样做,会发生什么取决于 @Transactional 注释的 propagation 属性,并在本节中描述:10.5.7 事务传播.基本上:PROPAGATION_REQUIRED 意味着相同的事务将用于两种方法,而 PROPAGATION_REQUIRES_NEW 开始一个新的事务.

b) if you do it, what happens depends on the propagation attribute of the @Transactional annotation and is described in this section: 10.5.7 Transaction propagation. Basically: PROPAGATION_REQUIRED means the same transaction will be used for both methods, while PROPAGATION_REQUIRES_NEW starts a new transaction.

关于您的评论:

当然,我继续阅读并意识到,当我使用代理时,第二种方法不会由事务代理管理,因此它就像任何其他方法调用一样.

Of course I kept reading and realized that, as I'm using proxies, this second method won't be managed by the transactional proxy, thus it's like any other method call.

在您的情况下情况并非如此(仅当两种方法都在同一个类中时).

That's not true in your situation (only if both methods were within the same class).

如果一个 bean 有方法 ab,并且 a 调用 b,那么 b 是在实际方法上调用的,而不是在代理上调用,因为它是从代理内部调用的(bean 不知道它被代理到了外部世界).

If a bean has methods a and b, and a calls b, then b is called on the actual method, not the proxy, because it is called from within the proxy (a bean doesn't know that it is proxied to the outside world).

proxy      bean  
a() -->    a()
            |
            V  
b() -->    b()

但是,在您的情况下,服务会注入一个 dao 对象,该对象本身就是代理,因此您会遇到这样的情况:

In your situation, however, a service would have an injected dao object, which would be a proxy itself, so you'd have a situation like this:

           proxy      bean
service    a() -->    a()
                       |
             /---------/
             |                 
             V
dao        b() -->    b()

这篇关于理解 Spring 事务 - 当一个事务方法调用另一个事务方法时会发生什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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