简体   繁体   English

Spring中的事务处理方法

[英]Transactional methods in Spring

I have got stuck a number of times asking myself why wasn't my code persisting the data in the database. 我被困了很多次,问自己为什么我的代码没有将数据持久化到数据库中。 I mean, I have got my simple method annotated with @Transactional and everyting seems to go fine, no problems. 我的意思是,我已经用@Transactional注释了我的简单方法,并且一切似乎都很好,没有问题。 After trying to discover the reason for some time I will eventually remember that I am actually calling my transactional method from the inside of the same class, and hence spring will promptly ignore the annotation. 在尝试找出原因之后,我最终会记得我实际上是在同一类内部调用事务方法的,因此spring将立即忽略该注释。 It happend to me that in those cases I was marking the method as transactional on my @Controller layer, which seemed to limit code re-usability. 我碰巧在那些情况下,我在@Controller层上将该方法标记为事务性的,这似乎限制了代码的可重用性。 So, I have two questions in regard of this problem: 因此,关于这个问题,我有两个问题:

  • On which level of the spring architecture is the @Transactional best placed ( @Controller , @Service etc..)? @Transactional最适合放置在Spring体系结构的哪个级别( @Controller@Service @Controller等。)?
  • Why exactly does spring ignore the annotation when the annotated method is called from the inside of the class? 当从类内部调用带注释的方法时,为什么spring会完全忽略注释?

The spring documentation is a very good source for explaining this. Spring文档是解释此问题的很好的资料。 At its most basic, when you are using spring with annotations like transactional, when spring injects an object it is actually injecting a proxy to that object. 最基本的说,当您使用带有注解(例如事务性)的spring时,spring注入对象时实际上是在注入该对象的代理。 This allows it to intercept method calls and do stuff like manage transactions. 这样,它就可以拦截方法调用并执行诸如管理事务之类的工作。 When you instantiate an object yourself or make a call to another instance method within the same class you are not calling through a spring proxy and it will not be able to manage that call. 当您自己实例化一个对象或对同一类中的另一个实例方法进行调用时,您不是通过spring代理进行调用的,它将无法管理该调用。

As for where the Transactional annotation should be placed this is dependent on your codebase and opinion on project structure. 至于应在何处放置事务注释,这取决于您的代码库和对项目结构的看法。 Personally, I place them as high up the call stack as logically makes sense. 就个人而言,我将它们放在逻辑上合理的情况下放在调用堆栈的上方。

On which level of the spring architecture is the @Transactional best placed (@Controller, @Service etc..)? @Transactional最适合放置在Spring体系结构的哪个级别(@ Controller,@ Service等。)?

Based on my experience, it is best placed on service layer. 根据我的经验,最好将其放在服务层上。 You can add it in other layers also but just be consistent about it. 您也可以将其添加到其他层中,但要保持一致。 Because if you add any more annotations based on this '@Transactional' annotation, it's behaviour should be same all across your application. 因为如果您基于此'@Transactional'注释添加更多注释,则它在整个应用程序中的行为应相同。

Why exactly does spring ignore the annotation when the annotated method is called from the inside of the class? 当从类内部调用带注释的方法时,为什么spring会完全忽略注释?

You can read about how Spring AOP works on based on proxies. 您可以阅读有关基于代理的Spring AOP的工作原理。 Here are your references - 这是您的参考资料-

Spring nested transactions 春季嵌套交易

@Transactional method calling another method without @Transactional anotation? @Transactional方法调用没有@Transactional注释的另一个方法?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM