Grails Gorm静态锁导致HibernateOptimisticLockingFailureException
我们有一个高并发的Grails应用程序,几个工作线程试图更新同一个域对象Message,但服务中实现的悲观锁定解决方案(事务设置为false)使用静态锁Grails Gorm静态锁导致HibernateOptimisticLockingFailureException,hibernate,grails,gorm,Hibernate,Grails,Gorm,我们有一个高并发的Grails应用程序,几个工作线程试图更新同一个域对象Message,但服务中实现的悲观锁定解决方案(事务设置为false)使用静态锁Message.lock(msg.id)导致许多情况下出现HibernateOptimisticLockingFailureException Facility.withTransaction { if (resp?.status == 200) { Message msgCopy = Message.lock
Message.lock(msg.id)
导致许多情况下出现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:行已由更新或删除
另一个事务(或未保存的值映射不正确):
[com.cds.healthdock.messaging.Message#58653744]
在messaging.OutboxService$\u pushMessageToPeer\u closure8.doCall(OutboxService.groovy:442)
位于org.grails.datastore.gorm.GormStaticApi.withTransaction(GormStaticApi.groovy:815)
<任何策略(除了例外)我都应该考虑?code>isDirty()isEmpty()下面是一篇关于这个问题的非常详细的文章。我的问题与您完全相同,我通过使用悲观锁定解决了它,即
- 启动交易
- 获取对象并通过static
方法锁定它lock()
- 更新对象
- 提交事务
但另一方面,代码似乎是在
withTransaction
中执行的。悲观锁定方法必须在事务中执行。我应该补充一点,从设计角度来看,两个线程试图为任何字段(包括状态)更新同一消息,如果响应为200,则消息应始终设置为softDelete。对邮件的任何其他更新都将变得无关紧要,并且可能会丢失或被覆盖。感谢您的文章。是的,这是一项交易,因为我们使用withTransaction。我们还有其他非事务性的方法。