在事务上下文中使用findBy [英] Using findBy in transactional context

查看:106
本文介绍了在事务上下文中使用findBy的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

鉴于:


  • 控制器 PersonController 带有 @Transactional action save

  • service PersonService 从控制器动作调用 populateProperties(PersonInstance)方法


I 'd喜欢根据一些数据在数据库中保存 personInstance 属性,如下所示:

  def personLookupData = PersonLookupData.findByUsername(personInstance.username)
personInstance.firstName = personLookupData.firstName



findByUsername 方法刷新hibernate会话并为了避免它(因为它给我提出了这里),我这样做:

  def personLookupData = PersonLookupData.withNewSession {Pers onLookupData.findByUsername(personInstance.username)} 
personInstance.firstName = personLookupData.firstName

做我想做的事情(让我使用 findBy 而不刷新会话),并且当只有 findBy s来使用,但是如果在不同地方使用更深的调用堆栈(以服务的方式)和更多的数据库查找,那么在任何地方使用 withNewSession 都会变得有点难看。 PersonLookupService ,它将在一个 withNewTransaction 中收集所有需要的数据c $ c> block并返回它,有没有其他的方法可以做到这一点?

解决方案

我想你应该将@Transactional从PersonControlller移动到PersonService。



如果您有更多服务电话要包含在同一个事务中,则需要使用事务边界网关,该网关标记为@Transactional,并调用所需的所有服务当前的商业案例。

这不是MVC组件控制交易的责任。事务边界由服务层处理。


Given:

  • controller PersonController with a @Transactional action save
  • service PersonService with a method populateProperties(PersonInstance) being called from the controller action

I'd like to populate personInstance properties based on some data already persisted in the database, like this:

def personLookupData = PersonLookupData.findByUsername(personInstance.username)
personInstance.firstName = personLookupData.firstName

The findByUsername method flushes the hibernate session and in order to avoid it (because it has been giving me problems described here), I do this:

def personLookupData = PersonLookupData.withNewSession { PersonLookupData.findByUsername(personInstance.username) }
personInstance.firstName = personLookupData.firstName

This does what I want (lets me use findBy without flushing the session), and this is fine when there is only a couple of findBys to use, but given a deeper call stack (in terms of services) and more database lookups in different places, using withNewSession everywhere becomes a bit ugly.

Apart from making a PersonLookupService which will collect all the required data in one withNewTransaction block and return it, is there any other nice (groovy) way of doing this?

解决方案

I think you should move @Transactional from PersonControlller to PersonService.

If you have more service calls to include in the same transaction, you need to use a Transaction boundary gateway, that's marked as @Transactional and calls all services you need for the current business case.

It's not the responsibility of the MVC components to control transactions. The transactions boundary are handled by the service layer.

这篇关于在事务上下文中使用findBy的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆