hibernate - 为什么我的 grails JMS 消息处理服务使用陈旧数据?

标签 hibernate grails jms

我们构建了一个 grails 应用程序,它通过 JMS 消息与遗留系统集成,并利用 JMS 队列分发大批量作业。我们使用 grails JMS 插件来支持这些消息传递需求。我们发现了一个不幸的一致性问题,我们正在尝试解决这个问题,可以使用一些帮助。

典型的流程是:

  • 一个外部系统更改了我们数据库中的状态并发送了一条消息,说明发生了状态更改
  • 我们的 grails 应用程序处理消息,从数据库中提取与外部进程刚刚写入的数据相同的数据(未为遗留系统修改的类/表启用 hibernate 辅助和查询缓存)。该消息包含大量数据,但我们仅使用 grails 应用程序中的类和标识符。
  • 如果我们的 JMS 处理服务在处理前一个事件时已经与数据交互,那么这些数据就是陈旧的。

  • 但是,如果我向显示相同数据的 Controller 发出 Web 请求,则它与数据库一致。

    我们的理论是在 JMS 事件的处理之间有一些数据缓存,大概是在 hibernate session 中。由于 grails 请求处理似乎做我们想要确保一致性的事情,我们认为我们应该用类似的代码包装我们的事件处理。如果 hibernate session 在 JMS 消息之间持久化数据,我们假设我们希望为每条消息设置和拆除 hibernate session 。不幸的是,我们对 grails-core 不够熟悉,无法确定这是在哪里完成的,以便我们可以根据需要重新调整该代码的用途……我们也没有验证这是我们的问题。

    显然,外部系统和我们的 grails 应用程序都写入同一个数据库是不理想的。随着时间的推移,我们正在通过迁移遗留系统来解决这个问题,因此将所有内容都移到 grails 应用程序中是需要的,但作为该问题的短期解决方案并不可行。

    最佳答案

    我是 JMS 插件的作者。

    使用默认监听器配置,每次收到消息时都会设置一个新的 hibernate session :

    https://github.com/gpc/grails-jms/blob/master/src/groovy/grails/plugin/jms/listener/adapter/PersistenceContextAwareListenerAdapter.groovy

    尝试在 JMS 接收消息开始时对域对象调用 .refresh()。如果这解决了问题,那么我们就会以某种方式泄漏 hibernate session 状态。我们很可能需要明确清除 hibernate 缓存。

    你能告诉我结果吗?

    关于hibernate - 为什么我的 grails JMS 消息处理服务使用陈旧数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4390654/

    相关文章:

    java - 在 JPA 中过滤引用实体数据

    java - Spring Data JPA ManyToOne 双向

    java - 请解释一下 spring MVC 、 hibernate 和 Spring security

    java - org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException :

    grails - java.lang.NoSuchMethodError:com.lowagie.text.pdf.BaseFont.getCharBBox(C)[I

    php - JMS 序列化器在 Mysql BLOB 反序列化上返回资源 id #xxx

    jms - openwire vs amqp,哪个性能更好

    grails - 在Grails 3.2.4中,具有.async.task调用的 Controller 将request.asyncStarted()设置为true,但不呈现响应

    unit-testing - Grails Spock 单元测试需要模拟事务管理器

    java - Apache Camel JMS - 异常没有通过请求/回复返回给调用者