当前位置: 首页 > 知识库问答 >
问题:

Grails Gorm静态锁定导致HibernateOptimisticLockingFailureException

华俊贤
2023-03-14

我们有一个高并发的Grails应用程序,有几个工作线程试图更新同一个域对象Message,但是在服务中使用静态锁Message.lock(msg.id)实现的悲观锁定解决方案(transactional设置为false)会导致许多< code > HibernateOptimisticLockingFailureException 的实例。

    Facility.withTransaction {
      if (resp?.status == 200) {
        Message msgCopy = Message.lock(msg.id)
        msgCopy.state = State.SoftDeleted
        msgCopy.save(flush: true)
      }
    }

静态锁如何导致HibernateOptimisticLockingFailure?我的理解是,静态锁将读取最新的持久版本。这只是另一个线程删除它的情况吗?

完全错误:

[com.cds.healthdock.messaging.消息]标识符[58653744]:乐观锁定失败;嵌套异常是org.hibernate.StaleObjectState异常:行被另一个事务更新或删除(或未保存的值映射不正确):[com.cds.healthdock.messaging.消息#58653744]在消息。Outbox Service$_pushMessageToPeer_closure8.do调用(OutboxService.groovy:442)在org.grails.datastore.gorm.GormStaticApi.with事务(GormStaticApi.groovy:815)

我应该考虑什么策略(除了捕捉异常)?< code > is dirty() < code > isEmpty()

共有1个答案

乐正嘉瑞
2023-03-14

这里有一篇关于这个问题的优秀且非常详细的文章。我遇到了与您完全相同的问题,我使用悲观锁定解决了这个问题,即。

    < li >开始交易 < li >获取对象并通过静态< code>lock()方法锁定它 < li >更新对象 < li >提交交易

看起来你在做类似的事情,但是我不知道你是否在交易中做,因为一方面你说

在服务中实现的悲观锁定解决方案(事务设置为 false)

但另一方面,代码似乎是在 withTransaction 中执行的。悲观锁定方法必须在事务中执行。

 类似资料:
  • 尝试可视化和理解同步。 对同步块使用静态锁定对象(代码a)和非静态锁定对象(代码B)之间有什么区别 它在实际应用中有什么不同 一方会有哪些陷阱而另一方不会 确定使用哪一个的标准是什么 代码A 代码B 笔记 上面的代码显示了构造函数,但是您可以讨论静态方法和非静态方法中的行为是如何不同的。另外,在同步块修改静态成员变量时使用静态锁是否有利? 我已经看过了这个问题的答案,但是还不清楚不同的使用场景是什

  • 我试图使用C++11的std::condition_variable,但是当我试图从第二个线程锁定与其关联的unique_lock时,我得到一个异常“资源死锁已避免”。创建它的线程可以锁定和解锁它,但不能锁定第二个线程,即使我非常肯定unique_lock不应该在第二个线程试图锁定它的地方已经锁定。 FWIW我在Linux中使用gcc4.8.1和-std=gnu++11。 我已经围绕conditi

  • 我在运行以下代码时遇到了一个奇怪的问题: 首先,代码是用OpenJDK-11和OpenJFX-11编译的,在Windows中运行良好(即退出call)。 然而,如果我在Linux(特别是Ubuntu20.04)上运行这个程序,调用会锁定线程,程序永远不会退出。注释出调用将使其重新正常工作。 我只是在(这是SystemLookAndFeel返回的结果)或者我在这里做了什么错误/意外的事情?

  • 我正在进行搜索,然后循环搜索结果。这会导致我的代码被锁定,更糟糕的是,它会锁定数据库,使其无法进一步使用。即使在浏览器关闭之后。当然,在我再次尝试我的代码之前,这种“锁定”似乎会在一段时间后被清除。我将改变我执行这项特定任务的方式,但我很好奇是什么导致了这种锁定。

  • 根据我在 Java 课上的知识 非静态同步方法:锁定获取特定对象 静态同步方法:类上的锁获取 我对此有点困惑,因为我们可以通过类名或对象名调用静态方法。 请假设我的类有4个方法,所有方法都是同步的。2个方法是静态的,2个不是静态的。如果我创建了我的类“对象1”的1个对象,并且还有2个线程Thread1和Thread2 问题1:如果我将尝试访问静态同步方法,使用对象1(或类名),这是否意味着“对象1

  • 问题内容: 注意: 这是不是重复,请仔细阅读题目 сarefully报价: 真正的问题是为什么代码有时在不应该运行的情况下仍然有效。即使没有lambda,该问题也会重现。这使我认为可能存在JVM错误。 在http://codingdict.com/questions/122889的评论中,我试图找出原因,导致代码行为从一个起点到另一个起点有所不同,而该讨论的参与者为我提供了一个建议,以创建一个单独