锁定Grails无法正常工作

时间:2011-06-29 14:23:20

标签: grails locking gorm

我在Grails中使用锁时遇到了一些问题。

情况如下:

我有一个User类,然后是另一个具有belognsTo = User Property的Class UserProperty。

现在为了避免用户同时修改此属性,我想锁定用户,然后修改/添加/删除新属性。

但锁似乎不起作用,因为在这两种情况下请求都会失败。伪代码看起来像这样:

User.lock(userId)
log.info "Starting modifiying properties"
addRemoveOrChangePropertiesToUser(userId)
log.info "Finsih modifing properties"
User.save(flush: true)

我期待的行为是,第一个请求通过并记录所有内容。直到那个(因为用户被锁定),第二个请求等待,然后对属性进行更改。

根据日志文件,我看到一个完全不同的行为。两个请求都在没有任何等待时间的情况下处理(almos simultationiusly)。

你有什么想法,我做错了什么?我是否错过了解与数据库锁定相关的一些概念?我怎样才能达到预期的行为?

谢谢, 尼古拉斯

3 个答案:

答案 0 :(得分:4)

我遇到了类似的问题,我的功能是在控制器中。我认为其他线程一旦命中.lock语句就应该被阻止,但那并没有发生。在交易中包装整个事情为我解决了问题。

这样的事情:

User.withTransaction {
    User.lock(userId)
    log.info "Starting modifiying properties"
    addRemoveOrChangePropertiesToUser(userId)
    log.info "Finsih modifing properties"
    User.save()
}

事后看来,这是有道理的。我怀疑交易是否需要提供明确的划分(工作单元),否则GORM / hibernate如何知道何时可以释放锁定?

控制器方法具有开放会话但不包含在事务中。默认情况下,服务方法包含在事务中,我怀疑我们不会在那里看到这个问题。

答案 1 :(得分:0)

我不确定锁是如何工作的。我的理解是它从OTHERS锁定实体,当他们从休眠会话中获取实体时更新同一个实例。

答案 2 :(得分:-2)

我不确定你是否正确实现了这一点。我认为你需要获得一个实例 - 然后将其锁定为......

def instance = Thing.get(1)
instance.lock()

然后尝试修改锁定的实例。

相关问题