Grails Gorm静态锁导致HibernateOptimisticLockingFailureException

时间:2016-09-13 23:10:39

标签: 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],标识符为[58653744]:   乐观锁定失败;嵌套异常是   org.hibernate.StaleObjectStateException:行已更新或删除   另一个事务(或unsaved-value映射不正确):   [com.cds.healthdock.messaging.Message#58653744]       在messaging.OutboxService $ _pushMessageToPeer_closure8.doCall(OutboxService.groovy:442)       在org.grails.datastore.gorm.GormStaticApi.withTransaction(GormStaticApi.groovy:815)

我应该考虑任何策略(除了捕获异常)? isDirty() isEmpty()

1 个答案:

答案 0 :(得分:0)

以下是关于此问题的优秀且非常详细的article。我和你有完全相同的问题,我通过使用悲观锁定来解决它,即

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

看起来你正在做类似的事情,但我无法判断你是否在交易中这样做,因为一方面你说过

  

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

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