了解Spring事务 – 当事务方法调用另一个事务方法时会发生什么?
只是为了理解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()
会发生什么? 事务已经存在的事实会导致没有新的交易产生,或者我在这里创建两个交易?
关于传播的文档(引用如下)似乎涵盖了这一点,但我想validation我的理解,这对于我的处女大脑来说有点多了解一下。
传播 :通常,在事务范围内执行的所有代码都将在该事务中运行。 但是,如果在事务上下文已存在时执行事务方法,则可以选择指定行为。 例如,代码可以继续在现有事务中运行(常见情况); 或者可以暂停现有交易并创建新交易。 Spring提供了EJB CMT熟悉的所有事务传播选项。 要了解Spring中事务传播的语义,请参见第10.5.7节“事务传播”。
两个答案:
a)不要这样做。 在服务层或dao层中使用@Transactional
,但不能同时使用两者(服务层是通常的选择,因为您可能希望每个服务方法有一个事务)
b)如果你这样做,会发生什么取决于@Transactional
注释的propagation
属性,并在本节中描述: 10.5.7事务传播 。 基本上: PROPAGATION_REQUIRED
表示两种方法都使用相同的事务,而PROPAGATION_REQUIRES_NEW
启动新事务。
关于你的意见:
当然,我一直在阅读并意识到,由于我正在使用代理,第二种方法不会由事务代理管理,因此它就像任何其他方法调用一样。
在你的情况下这不是真的(只有当两个方法都在同一个类中时)。
如果bean有方法a
和b
,并且调用b
,则在实际方法而不是代理上调用b
,因为它是从代理中调用的(bean不知道它是代理到外部世界的) )。
proxy bean a() --> a() | V b() --> b()
但是,在你的情况下,一个服务会有一个注入的dao对象,它本身就是一个代理,所以你会遇到这样的情况:
proxy bean service a() --> a() | /---------/ | V dao b() --> b()