I have a Grails application that executes to API calls, gets the reply, processes the data within the reply and then displays some charts and tables ion a results page.
The user enters some data and clicks a button to execute. So without any locking implemented if two users click that button at or near the same time what happens is that either one or both could wind up with no results being charted on the results page. I need to prevent this from happeneing, preferably by making the second request wait until the grails executes the first request.
I've read about optimistic vs. pessimistic locking but nothing really explains HOW to implement it and where. In the controller? In the service?
Is it a call like this and where?
myInstance.save flush:true, failOnError: true
Any help understanding this is appreciated I couldn't find a whole lot of information out there about this.
You need to implement cross-session request locking.
The easiest way to do it is having a singleton map to prevent parallel execution of requests. That might look like:
class LockingSomethingController {
static scope = "singleton"
Map locks = new ConcurrentHashMap()
def lockMe( String id ) {
if( locks[ id ] ){
render status:400, text:'locked'
return
}
locks[ id ] = true
try{
doSomeSeriousStuff()
}finally{
locks.remove id
}
}
}