【问题标题】:How do you unlock a domain object after calling lock()?调用 lock() 后如何解锁域对象?
【发布时间】:2014-02-17 01:13:05
【问题描述】:

如果你在域实例或类上静态调用lock(),然后你决定对对象没有任何事情,有没有办法手动立即释放锁?

【问题讨论】:

  • 它被锁定以进行更新,因此您可以在域对象上调用save() 来释放锁定,尽管它可能很昂贵。

标签: grails grails-orm grails-2.0


【解决方案1】:

为了扩展dmahapatro 所说的内容,docs 表示:

事务提交时自动释放锁

因此,一旦您调用.save(),当该保存的事务提交时(通常在服务结束方法时),锁将被释放。

您可能还想查看这些docs

【讨论】:

  • 我已经看过你提到的文档。我希望他们只是遗漏了一些东西,即一种扭转不需要的锁的方法。我想没有其他办法,或者您或文档会提到它?那么嵌套事务呢?我可以开始一个嵌套事务,锁定一行,然后在不需要锁定的情况下回滚嵌套事务吗?
  • @greymatter 嗯,不确定嵌套事务,但我确实发现此链接可能有帮助? grails.1312388.n4.nabble.com/…
  • 这不是我所希望的,但我将把它标记为已回答。谢谢!
  • 当然有问题...例如抛出一个异常,所以 spring 会自动回滚......但你出于 X 原因捕获它。您可能需要手动解除锁定。也许丢弃会释放它?
【解决方案2】:

在提交事务时释放锁,但在调用 save() 时不会释放,因为在 save() 之后事务仍然存在。当代码执行离开服务方法或刷新休眠会话(http请求完成后,会话被刷新并清除)时,事务可能会被提交。

释放锁的最佳方法是使用手动事务处理。在服务中这样做:

def saveUser(Long userId)
{
    User.withNewTransaction { TransactionStatus status ->
        User user = User.lock(userId)
        user.save()
    }
}

【讨论】:

  • 服务方法自动放入事务中(默认)。
  • 是的,但它发生得太晚了,另一个并发事务看不到它,服务可以调用其他服务,可能需要几分钟左右才能提交事务。
  • 我明白了,我没有看清楚你的答案。感谢您的详细说明。
猜你喜欢
  • 2018-09-02
  • 2019-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-16
  • 2022-12-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多