If we add afterUpdate event code on a domain object (e.g. our Session object) in grails:
- Is it called after the update has been committed, or after it is flushed, or other?
- If the update failed (e.g. constraint, or optimistic lock fail), will the after event still be called?
- Will afterUpdate be in the same transaction as the update?
- will the commit of the service method which did the update wait till the afterUpdate method is finished, and, if so, is there any way round this (except creating a new thread)?
We have a number of instances of our grails application running on mutliple tomcats. Each has a session expiry quartz job to expire our session (domain object)
The job basically says getAllSession with lastUpdated > xxx, then loops through them calling session.close(Session.Expired)
Session.close just sets the session.status to Expired.
In theory, the same session could be closed twice at the same time buy the job running on two servers, but this doesn't matter (yet)
Now we want to auto cashout customers with expired (or killed) sessions. The cashout process entails making calls to external payment systems, which can take up to 1 minute, and may fail (but should not stop the session from being closed, or 'lock' other sessions)
If we used the afterUpdate on the session domain object, we can check the session.status, and fire of the cashout, either outside of the transaction, or in another thread (e.g. using Executors). But this is very risky - as we dont know the exact behaviour. E.g. if the update failed, would it still try to execute the afterUpdate call? We assume so, as we are guessing the commit wont happen till later.
The other unknown is how calling save and commit works with optimistic locking. E.g. if you call save(flush=true), and you dont get an error back, are you guaranteed that the commit will work (baring the db falling over), or are there scenarios where this can fail?