複数のワーカースレッドが同じドメインオブジェクトMessageを更新しようとしているが、同時実行性が高いGrailsアプリケーションがありますが、静的ロック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()
レスポンスが200ならば、メッセージを常にsoftDeleteに設定する必要があります。ステータスを含むすべてのフィールドに対して同じメッセージを更新しようとする2つのスレッドについて、デザインの観点から追加する必要があります。メッセージに対するその他の更新は無関係になり、失われたり上書きされたりする可能性があります。 –