Java 理解Spring事务——当一个事务性方法调用另一个事务性方法时会发生什么?
为了理解Spring事务的工作原理,我想知道在下面的情况下会发生什么,其中一个标记为Java 理解Spring事务——当一个事务性方法调用另一个事务性方法时会发生什么?,java,spring,transactions,Java,Spring,Transactions,为了理解Spring事务的工作原理,我想知道在下面的情况下会发生什么,其中一个标记为@Transactional的方法调用另一个标记为@Transactional的方法 假设配置使用所有默认设置 @Service("myService") @Transactional public MyService{ public void myServiceMethod(){ myDAO.getSomeDBObjects(); } } @Repository("myDAO") @T
@Transactional
的方法调用另一个标记为@Transactional
的方法
假设配置使用所有默认设置
@Service("myService")
@Transactional
public MyService{
public void myServiceMethod(){
myDAO.getSomeDBObjects();
}
}
@Repository("myDAO")
@Transactional
public MyDAOWithUsesBeyondMyService{
public void getSomeDBObjects(){...}
}
现在,如果我输入MyService.myServiceMethod()
,它显然会启动一个事务。然后,当深入到myDAO.getSomeDBObjects()
时会发生什么?事务已经存在的事实是否会导致没有新事务生成,或者我在这里创建了两个事务
关于传播的文档(下面引用)似乎涵盖了这一点,但我想验证一下我的理解,这对我的处女大脑来说是一个一次性理解的小问题
传播:通常,所有代码
在事务范围内执行
将在该事务中运行。然而,
您可以选择指定
发生以下情况时的行为:
事务方法在以下情况下执行:
事务上下文已存在。
例如,代码可以继续运行
在现有事务中(在
一般情况);还是现有的
可以挂起事务并创建新的
已创建事务。春天提供一切
事务传播选项的定义
熟悉EJBCMT。了解
事务的语义
在春季传播,请参见第节
10.5.7,“交易传播”
两个答案:
a) 不要这样做。在服务层或dao层中使用@Transactional
,但不能同时使用两者(服务层是通常的选择,因为您可能希望每个服务方法有一个事务)
b) 如果执行此操作,则发生的情况取决于@Transactional
注释的传播
属性,本节对此进行了描述:。基本上:PROPAGATION\u REQUIRED
意味着相同的事务将用于两种方法,而PROPAGATION\u REQUIRES\u NEW
启动一个新事务
关于您的评论:
当然,我一直在阅读并意识到,在使用代理时,第二个方法不会由事务代理管理,因此它与任何其他方法调用一样
在您的情况下不是这样的(只有当两个方法都在同一个类中时)
如果一个bean有方法a
和b
,并且a
调用b
,那么b
在实际的方法上被调用,而不是在代理上,因为它是从代理内部被调用的(一个bean不知道它被代理到外部世界)
然而,在您的情况下,服务会有一个注入的dao对象,它本身就是一个代理,所以您会遇到这样的情况:
proxy bean
service a() --> a()
|
/---------/
|
V
dao b() --> b()
谢谢,是的,我不打算这样做,但是当我意识到我已经在服务类级别声明了@Transactional,并且服务的一个方法正在调用服务的另一个方法(都是Transactional)时,我突然想到了这个问题。当然,我一直在阅读并意识到,当我使用代理时,第二种方法不会由事务代理管理,因此它就像任何其他方法调用一样(这足以让新启动的大脑感到困惑)。:)但这让我很好奇,确保我理解了所有工作原理的细节,你已经很好地为我澄清了这一点。谢谢@大卫,我想你误解了代理的概念。阅读我的更新。你是绝对正确的,我的评论是错误的(事实上我在没有说的情况下改变了假设),但我理解你所说的,在所有这些之后,我认为整个事情现在已经在我的脑海中根深蒂固了。感谢您的更新和伟大的图表,我相信许多其他人会发现它在他们的搜索在未来有用@SeanPatrickFloyd您能看一下并提供您的专家建议吗?
proxy bean
service a() --> a()
|
/---------/
|
V
dao b() --> b()