hibernate - SQL data accessed concurrently - StaleObjectStateException -
class document{ hasmany{ changes: pendingchange} } class documentservice{ def acceptall(){ def owner = document.get(params.id) def changes = owner.changes.findall{it.status == "pending"}.collect{it.id} executorwrapperservice.processclosure({ changes.each{pc -> //*1 changeservice.accept(pc) } }, owner) redirect(url: request.getheader('referer')) } } class documentcontroller{ def index(){ def result = [:] def owner = document.get(params.id) //even if processing running, want show how many left. accept/reject buttons disabled if processingpc true result.changes = owner.changes.findall{it.status == "pending"} if(executorwrapperservice.hasrunningprocess(owner)){ //*2 result.processingpc = true } . . . return result } } class executorwrapperservice { def executorservice concurrenthashmap<object,java.util.concurrent.futuretask> activefuture = [:] def processclosure(clos,owner){ owner = "${owner.class.name}:${owner.id}" //see if got process running owner def existingfuture = activefuture.get(owner) if(!existingfuture){ //start new thread , store process def future = executorservice.submit(clos java.util.concurrent.callable) activefuture.put(owner,future) }else{ //if previous process owner done, remove , start new 1 if(existingfuture.isdone()){ activefuture.remove(owner) processclosure(clos,owner) } //if not done, else } } def hasrunningprocess(owner){ owner = "${owner.class.name}:${owner.id}" // there no process running owner if(activefuture.get(owner) == null){ return false // there process, done. }else if(activefuture.get(owner).isdone()){ activefuture.remove(owner) return false // have running process }else if(activefuture.get(owner).isdone() == false){ return true } } }
the above code demonstrates happening. on index screen display list of changes. when user clicks accept all
button, documentservice.acceptall
called. new thread created , changes start applying. has effect on database objects. request redirected index
. because want disable actions on pending changes while processing happening, executorwrapperservice.activefuture
used tell documentcontroller if there processing happening document. when executing documentcontroller.index
read database fields display, no writes happening.
when performing above action, 1 of following errors:
events.patcheddefaultflusheventlistener - not synchronize database state session org.hibernate.staleobjectstateexception: row updated or deleted transaction (or unsaved-value mapping incorrect): [document#1495]
on line *1 , or same error on line *2. believe problem thread creating. trying figure how should use transactions or sessions solve this, havent made yet.
Comments
Post a Comment