我們有一個高度併發的Grails應用程序,有幾個工作線程嘗試更新同一個域對象Message,但悲觀鎖定解決方案在服務中使用靜態實現(事務設置爲false)鎖Message.lock(msg.id)
導致HibernateOptimisticLockingFailureException
的許多實例。Grails Gorm靜態鎖定導致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)
任何策略,我應該考慮(比捕捉異常等)? isDirty()
isEmpty()
我應該添加從設計的角度來看,圍繞兩個線程嘗試更新包括Status在內的任何字段的相同消息,如果響應是200,那麼消息應該始終設置爲softDelete。對消息的任何其他更新都變得無關緊要,並且可能會丟失或覆蓋。 –