We've built a grails application which integrates with a legacy system through JMS messages and distributes large batch jobs leveraging a JMS queue. We use the grails JMS plugin in order to support these messaging needs. We've discovered an unfortunate consistency problem that we're trying to solve and could use some help.
The typical process flow is:
- An external system changes state in our database and sends a message that the state change occurred
- Our grails application processes the message, pulling the same data from the database as was just written by the external process (hibernate secondary and query caching are not enabled for the classes/tables modified by the legacy system). The message has a lot of data, but we just use the class and identifier from our grails application.
- These data are stale if our JMS processing service had already interacted with the data when processing a previous event.
However if I make a web request to a controller which displays the same data, it is consistent with the database.
Our theory is that there is some caching of data between processing of JMS events, presumably in a hibernate session. Since the grails request processing seems to do what we desire to ensure consistency, we're thinking that we should be wrapping our event processing with similar code. If hibernate sessions are p开发者_如何学Cersisting the data between JMS messages, we're presuming that we're looking to setup and tear down of hibernate sessions for each message. Unfortunately we're not familiar enough with grails-core to identify where this is done so that we can repurpose that code for our needs...nor have we verified that this is our problem.
Obviously it isn't ideal that both an external system and our grails application are writing to the same database. We're addressing this issue over time with a migration off of the legacy system, so moving everything into the grails application is desired but not feasible as a short-term solution to the problem.
I am the author of the JMS plugin.
With the default listener configuration, a new hibernate session is setup each time a message is received:
https://github.com/gpc/grails-jms/blob/master/src/groovy/grails/plugin/jms/listener/adapter/PersistenceContextAwareListenerAdapter.groovy
Try calling .refresh() on your domain object at the start of your JMS receiving message. If this fixes the problem, then we are somehow leaking hibernate session state. It's likely we need to explicitly clear the hibernate cache.
Can you please let me know of the results.
精彩评论