【问题标题】:Is it possible to force flush a domain being saved in a service?是否可以强制刷新保存在服务中的域?
【发布时间】: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


【解决方案1】:

您可以创建一个在完成后将持续到 DDBB 的事务。

MyDomain.withTransaction{
        somecode()
}

【讨论】:

  • 遗憾的是,这对我不起作用。我无法让它正常工作。我最终只是回到控制器级别并在向 RabbitMQ 发送请求之前让域保存。
猜你喜欢
  • 2013-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-25
  • 1970-01-01
相关资源
最近更新 更多