【发布时间】:2015-11-30 23:10:52
【问题描述】:
在服务中保存域对象时,在保存域时使用flush: true,在我必须使用该对象之前,该对象没有得到保存。
Domain domain = new Domain(property: something.toString()).save(failOnError: true, flush: true)
我不确定如何在我正在使用的任一服务中强制刷新休眠会话。
在某些情况下,我正在对 API 服务进行 API 调用,该调用会转到另一个服务,我在其中保存域,然后返回 API 服务,然后将字符串添加到 RabbitMQ 队列,然后返回 200OK给用户。但是因为域没有被保存在第二个服务中,所以当项目被添加到队列中时,rabbitMQ 在域被保存之前处理消息。
编辑:
我目前的修复:
API 控制器:
def apiActionCreate()
{
Map returnMap = apiService.createAction(params, request)
rabbitSend staticQueue, [id: returnMap.id.toString()]
}
API 服务:
Map createAction(GrailsParameterMap params, HttpServletRequest request)
{
//do some logic related to a related domain
seperateService.someAction(domain.id)
}
我保存域的服务:
Map someAction(UUID id)
{
Domain domain = new Domain(property: something.toString()).save(failOnError: true, flush: true)
}
【问题讨论】:
-
可能是因为[尚未提交]交易?
-
以上正是该实例尚不存在的原因。域实例上的
flush: true提示就是这样。提示 Hibernate 将任何挂起的 SQL 刷新到数据库。但是,根据您的事务隔离级别,这些更改可能对其他线程或 Hibernate 会话不可见。您可以考虑设置一个限制较少的隔离级别,但这具有幻读或脏读的缺点(取决于您选择的隔离级别)。 -
服务方法是
@Transactional吗? -
尝试在您的服务中加入
static transaction=false -
您的代码看起来与我在应用程序中广泛使用的代码相似,没有任何问题。控制器调用服务,服务使用 flush:true 标志持久化数据。我没有使用 failOnError:true 但这不应该有任何区别。而且,我的服务不是跨国的。你有这样的属性吗?如果可能的话,你能在 github 中推送某些代码来重现问题吗?
标签: grails rabbitmq grails-domain-class grails-2.4 grails-services