I have a grails service method, load, that I only want one user at a time to be able to run. I have tried using Grails pessimistic lock but it only sometimes works. In my controller, I have:
try {
def country = Country.lock(id)
myService.load(country)
} catch (CannotAcquireLockException ex) {
flash.message = "Another user is modifying ${Country.get(id)}"
}
What is the best way to make load method of myService atomic?
What if I want two methods to be atomic (When one is executing, neither can execute)?
My service's method:
def load(id) {
def country = Country.get(id)
country.states.each {
...
it.save(flush: true)
}
}
Adding the synchronized keyword to this method causes a StaleObjectStateException on the save.
Grails services are singletons by default which takes care of part of your problem. You should also make your service method synchronized to achieve what you want:
def synchronized load(country) { ... }
You can use @synchronized annotation with a custom synchronization lock. This way you won't be synchronizing this (whole service class), only the given method.
Code sample
class MyCustomService
private final myLock = new Object()
@Synchronized("myLock")
def myRunOneAtATimeMethod(int x, int y)
return x+y
More about synchronization: http://groovy.codehaus.org/gapi/groovy/transform/Synchronized.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With