了解Spring事务 - 当事务方法调用另一个事务方法时会发生什么?

时间:2010-11-13 08:17:11

标签: java spring transactions

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

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

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

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

现在,如果我要输入MyService.myServiceMethod(),那么显然会启动一项交易。然后,钻进myDAO.getSomeDBObjects()会发生什么?交易已经存在的事实会导致没有新的交易产生,或者我是否在这里创建了两笔交易?

关于传播的文档(如下所述)似乎涵盖了这一点,但我想验证我的理解,这对我的处女大脑来说有点多了解一下。

  

传播:通常是所有代码   在事务范围内执行   将在该交易中运行。然而,   你可以选择指定   在a。的情况下的行为   事务方法在执行时执行   事务上下文已存在。   例如,代码可以继续运行   在现有的交易中(   常见情况);或现有的   交易可以暂停和新的   交易创建。春天提供所有   事务传播选项   熟悉EJB CMT。阅读   交易的语义   在Spring中传播,参见章节   10.5.7,“交易传播”。

1 个答案:

答案 0 :(得分:39)

两个答案:

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

b)如果您这样做,会发生什么取决于propagation注释的@Transactional属性,并在本节中进行了描述:10.5.7 Transaction propagation。基本上:PROPAGATION_REQUIRED表示同一事务将用于两种方法,而PROPAGATION_REQUIRES_NEW启动新事务。

关于您的评论:

  

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

在你的情况下情况并非如此(只有两种方法都属于同一类)。

如果bean有方法ab以及a调用b,则会在实际方法上调用b,而不是代理,因为它是从代理中调用的(bean不知道它代理了外部世界)。

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

然而,在你的情况下,服务会有一个注入的dao对象,它本身就是一个代理,所以你会遇到这样的情况:

           proxy      bean
service    a() -->    a()
                       |
             /---------/
             |                 
             V
dao        b() -->    b()
相关问题