hibernate - Grails Gorm静态锁定导致HibernateOptimisticLockingFailureException

标签 hibernate grails gorm

我们有一个高并发性的Grails应用程序,有多个工作线程试图更新同一个域对象Message,但是使用静态锁Message.lock(msg.id)在服务中实现的悲观锁定解决方案(事务性设置为false)会导致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.Message] with identifier [58653744]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.cds.healthdock.messaging.Message#58653744] at messaging.OutboxService$_pushMessageToPeer_closure8.doCall(OutboxService.groovy:442) at org.grails.datastore.gorm.GormStaticApi.withTransaction(GormStaticApi.groovy:815)



我应该考虑采取什么策略(除了捕获异常(exception))? isDirty() isEmpty()

最佳答案

这是有关此问题的出色且非常详细的article。我遇到了与您完全相同的问题,并且通过使用悲观锁定来解决了该问题,即

  • 开始交易
  • 获取对象并通过静态lock()方法
  • 将其锁定
  • 更新对象
  • 提交事务

  • 看起来您正在执行类似的操作,但是我无法确定您是否在交易中执行此操作,因为一方面您说

    the pessimistic locking solution implemented in the service (with transactional set to false)



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

    关于hibernate - Grails Gorm静态锁定导致HibernateOptimisticLockingFailureException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39480276/

    相关文章:

    grails - 如何将域类与另一个域类的两个实例映射

    hibernate - Grails组合键上的一对多映射stalestaleException

    grails - Grails-尝试删除对象,但它们又回来了

    java - JPA 配置到底是什么?

    java - HSQLDB 数据库中神秘的完整性约束违规

    spring - 在Grails中加载bean时发生ClassNotFound异常

    java - grails 应用程序不再允许我在本地主机上发送电子邮件

    java - 在 Grails 中调整图像大小

    java - JBoss 中多个 War 应用程序的多个 hibernate 配置

    java - 如何在某些情况下忽略@SQLDelete注释