3

我有一个 grails 服务方法 load,我一次只希望一个用户能够运行。我曾尝试使用 Grails 悲观锁,但它有时才有效。在我的控制器中,我有:

try {
    def country = Country.lock(id)
    myService.load(country)
} catch (CannotAcquireLockException ex) {
    flash.message = "Another user is modifying ${Country.get(id)}"
}

使 myService 的加载方法原子的最佳方法是什么?

如果我希望两种方法是原子的(当一个方法正在执行时,两者都不能执行)怎么办?

我的服务方法:

def load(id) {
    def country = Country.get(id)
    country.states.each {
        ...
        it.save(flush: true)
    }
}

将 synchronized 关键字添加到此方法会导致保存时出现 StaleObjectStateException。

4

3 回答 3

2

您可以使用@synchronized带有自定义同步锁的注释。这样你就不会同步this(整个服务类),只有给定的方法。

代码示例

class MyCustomService

private final myLock = new Object()

@Synchronized("myLock")
def myRunOneAtATimeMethod(int x, int y)
    return x+y 

有关同步的更多信息:http: //groovy.codehaus.org/gapi/groovy/transform/Synchronized.html

于 2013-06-24T15:05:49.657 回答
2

Grails 服务默认是单例的,它可以解决您的部分问题。您还应该使您的服务方法同步以实现您想要的:

def synchronized load(country) { ... }
于 2012-12-27T00:18:19.083 回答
1

这可以使用ReentrantLock作为一个普通的 Java 同步问题来解决。我可以使用 isLocked 返回错误,而不是让用户等待锁做同样的事情。

于 2012-12-27T01:31:00.657 回答