在事务上下文中使用findBy [英] Using findBy in transactional context
问题描述
- 控制器
PersonController
带有@Transactional
actionsave
- 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
actionsave
- service
PersonService
with a methodpopulateProperties(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 findBy
s 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屋!