简体   繁体   English

在 Spring Boot 应用程序中在哪里指定 @Transactional 注释?

[英]Where to specify @Transactional annotation in a Spring Boot app?

In the context of a recent Spring Boot app (v. 2.7.0), there are a number of options for where the @Transactional annotation is applied在最近的 Spring Boot 应用程序 (v. 2.7.0) 的上下文中,有许多选项可用于应用@Transactional注释

Controller or Service?控制器还是服务?

Almost universally it seems that service is recommended, but it's not entirely clear why.几乎普遍认为服务是推荐的,但并不完全清楚为什么。

Implementation class or interface?实现类还是接口?

Assuming we choose to apply the annotation to our services and those services implement an interface, should we annotate the service interface or the implementation class?假设我们选择将注解应用于我们的服务并且这些服务实现了一个接口,我们应该注解服务接口还是实现类?

In older versions of the Spring docs , it was recommended to annotate the class旧版本的 Spring 文档中,建议对类进行注释

Spring recommends that you only annotate concrete classes (and methods of concrete classes) with the @Transactional annotation, as opposed to annotating interfaces. Spring 建议您仅使用 @Transactional 注释来注释具体类(和具体类的方法),而不是注释接口。 You certainly can place the @Transactional annotation on an interface (or an interface method), but this works only as you would expect it to if you are using interface-based proxies.您当然可以将 @Transactional 注释放在接口(或接口方法)上,但这仅在您使用基于接口的代理时才起作用。 The fact that Java annotations are not inherited from interfaces means that if you are using class-based proxies (proxy-target-class="true") or the weaving-based aspect (mode="aspectj"), then the transaction settings are not recognized by the proxying and weaving infrastructure, and the object will not be wrapped in a transactional proxy, which would be decidedly bad. Java 注释不是从接口继承的事实意味着,如果您使用基于类的代理 (proxy-target-class="true") 或基于编织的方面 (mode="aspectj"),那么事务设置是不被代理和编织基础设施识别,并且对象不会被包装在事务代理中,这将是非常糟糕的。

But this advice does not appear in the 5.2.X version of the docs, so I'm wondering if it still applies?但是这个建议没有出现在 5.2.X 版本的文档中,所以我想知道它是否仍然适用? Based on my testing it seems that applying the @Transactional annotation to interfaces does work in a Spring Boot app with the default proxying behaviour.根据我的测试,似乎将@Transactional注释应用于接口确实可以在具有默认代理行为的 Spring Boot 应用程序中工作。

@Transactional is most commonly used at service level, though there is nothing stopping you from making your controller methods transactional. @Transactional最常用于服务级别,尽管没有什么能阻止您使控制器方法具有事务性。 It really depends on how you structure your application.这实际上取决于您如何构建应用程序。

IMHO making your service layer transactional is a better approach.恕我直言,使您的服务层事务化是一种更好的方法。 It is typically at this level that you might be calling other persistence methods (DAOs, repositories, etc).通常在这个级别,您可能会调用其他持久性方法(DAO、存储库等)。 There could be reads/writes across multiple tables, so it makes the service layer a good place to define transaction boundaries.可能存在跨多个表的读/写,因此它使服务层成为定义事务边界的好地方。

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

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