Spring 的外观、服务接口和事务代理
情况
用户很可能不会直接与各种服务对象(POJO 或会话 Bean)进行交互,因为使用 Facade 模式将不同的单一服务收集到一组中。
@Transactional
注解应用于单个服务的方法级别,而不是应用于 Facade 的方法。
这遇到了一个实际问题——如果服务没有接口,Spring 就无法为它们使用良好的事务代理,从而导致各种复杂情况。
问题
什么是理想的实践?
- 为了良好的代理而创建单个服务接口,
- 或者将 @Transactional 注释移至 Facade 方法(从而在内部使用服务也必须流经 Facade 以确保事务)。
- 还是别的什么?
您的现场经验是什么?我也愿意从更广泛的角度考虑。
Situation
There is a high chance that users will not interact directly with the various Service objects (POJOs or Session Beans), since using the Facade pattern the different single services are collected into one bunch.
The @Transactional
annotation is applied on the level of methods of single services, as opposed to on the methods of the Facade.
This meets a practical problem - if the services have no interface, Spring can't use nice transaction proxies for them, leading to various complications.
Question
What is a desired practice?
- Creating single service interfaces for the sake of nice proxies,
- or moving the
@Transactional
annotations to the Facade methods (whereby internally using the services also have to flow through the Facade to ensure transactions). - or else?
What is your field experience? I'm also open for considerations from a wider perspective.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果服务没有接口,Spring 仍然可以通过使用 CGLIB 代理,在大多数情况下它工作得很好。当服务有一些接口,但事务方法不是这些接口的一部分时,就会出现真正的问题。
然而,将 @Transactional 应用于 Facade 方法可能是一个更清晰的解决方案,因为 Facade 接口定义了清晰的事务边界。如果您担心在这种情况下使用没有 Facade 的服务,您可以将
@Transactional
应用于服务以及 Facade 方法。在这些情况下,调用 Facade 方法时创建的事务为 传播到服务方法。If service has no interfaces, Spring still can apply transactional aspect to it by use of CGLIB proxies, in most cases it works fine. Real problems arise when service has some interfaces, but transactional method is not a part of these interfaces.
However, applying
@Transactional
to Facade methods can be a cleaner solution, since Facade interface defines clear transaction boundaries. If you worry about using services wihtout Facade in this case, you can apply@Transactional
to services as well as to Facade methods. In these case transactions created when you call Facade methods are propagated to the service methods.放置事务边界的唯一标准应该是业务逻辑标准而不是技术问题。如果服务方法应该是原子操作,那么就在那里管理事务。如果您的外观可以组合 2 个或多个服务调用,并且它们一起应该“执行全部或不执行”,这意味着事务应该放在外观中。正如 axtavt 提到的,cglib 代理可用于代理没有接口的类。
我还推荐 Mark Richards 的这个系列: http:// www.ibm.com/developerworks/views/java/libraryview.jsp?search_by=transaction+strategies:
The only criteria for placing transaction boundaries should be business logic criteria not technical issues. If services methods should be atomic operations then manage transactions there. If your facade can combine 2 or more service calls and they together should be "execute all or nothing", this means the transaction should be put in facade. As axtavt mentioned, cglib proxies can be used to proxy classes with no interfaces.
I also recommend this series by Mark Richards: http://www.ibm.com/developerworks/views/java/libraryview.jsp?search_by=transaction+strategies: