我们有一个高并发的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()
答案 0 :(得分:0)
以下是关于此问题的优秀且非常详细的article。我和你有完全相同的问题,我通过使用悲观锁定来解决它,即
lock()
方法看起来你正在做类似的事情,但我无法判断你是否在交易中这样做,因为一方面你说过
服务中实现的悲观锁定解决方案(事务设置为false)
但另一方面,代码似乎在withTransaction
内执行。必须在事务中执行悲观锁定方法。