We are developing a Grails 2.0 application that used to run smoothly on MySQL.
We asked our administrators to switch to PostgreSQL, which they prefer
We have added many new features to the application, including one that causes us a problem: an asynchronous third-party web service request
So, we have a created domain object, let it ask a question. When closing afterInsert , a Resource is created to subsequently save the result of the call to the external web service.
class Question implements Serializable { static hasMany = [resources: Resource] static constraints = { resources(nullable: true) } def afterInsert() { Resource.withNewSession { Resource txt = Resource.create(null) this.addToResources(txt) } } Resource retrieveResource(){ return this.resources.find{ it instanceof Resource } } static Question create(Map params) throws SaveDomainException {
We create the question as follows:
//first we create question and save it def question = Question.create(params) question.save(flush:true, insert:true) getThirdPartyService().doCallAsync((int)req.retrieveResource().id)
and ThirdPartyService as the doCallAsync method that spawns the ExecutorService (obtained through the grails executor plugin, so this is not a dangerous "Hibernate Session-Thread" problem) which executes a simple Resource.get(res_id) with the identifier obtained as shown above.
The problem is that with PostgreSQL and pooled = true in DataSource.groovy , get sometimes returns a null, sometinmes resource object.
We tested three different queries: a get(id) , a findById(id) and executeQuery with highlighted.
The stranger thing is that with the three lines above in the same method, we sometimes have different results. Only one out of three returns null, or three returns null, or none (which is the expected behavior, I remember)
We turned on PostgreSQL query logs to find out if this is a Hibernate caching problem, but all three queries are displayed in the logs, so hibernate occurs every time the database is reset. We see a resource insert with the correct identifier, followed by a commit, followed by three choices (which are provided with the correct resource identifier)
Does anyone have a hint that we are going to check further to find out where this error came from? (we tried to change the connection pool, no luck)
Last, if we add Thread.sleep(1000) (which is gory, but for testing purposes only ;-)) before the requests, everything runs smoothly. So this is apparently a visibility problem between postgres processes, but we have no idea how to solve this problem.