Grails のサービス内のエンティティをロックしようとしています。
コード:
TheEntity entityForUpdate = TheEntity.lock(entityId)
(...) // some code
entityForUpdate.save()
このコードは、同時アクセスが発生するまで機能します。これが発生すると、最初のスレッドがコードを実行している間、1 つのスレッドがロックされたままになります。ロックが解放されると、例外がスローされます。
ERROR errors.GrailsExceptionResolver - StaleObjectStateException occurred when processing request: [POST] /Portal/Controler/theMethod - parameters:
param1: 18
param2: 86,32
Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [core.TheEntity#133]. Stacktrace follows:
Message: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [core.TheEntity#133]
Line | Method
->> 96 | lock in org.hibernate.dialect.lock.SelectLockingStrategy
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 1441 | lock in org.hibernate.persister.entity.AbstractEntityPersister
| 110 | upgradeLock . . . . . . . . . . . . . in org.hibernate.event.def.AbstractLockUpgradeEventListener
| 86 | onLock in org.hibernate.event.def.DefaultLockEventListener
| 774 | fireLock . . . . . . . . . . . . . . in org.hibernate.impl.SessionImpl
| 758 | lock in ''
| 665 | doInHibernate . . . . . . . . . . . . in org.springframework.orm.hibernate3.HibernateTemplate$10
| 406 | doExecute in org.springframework.orm.hibernate3.HibernateTemplate
| 374 | executeWithNativeSession . . . . . . in ''
| 663 | lock in ''
| 148 | lock . . . . . . . . . . . . . . . . in
...
なぜそれが起こるのか理解できません。lock メソッドがこの例外をスローするのはなぜですか?
編集:
問題を回避するために、エンティティからバージョンを削除することを最終的に選択しました。
class TheEntity {
...
static mapping = {
version false
}
...
}
更新されたデータを取得するために、サービス メソッドのトランザクション モードも READ_COMMITED に設定しました。
@Transactional(isolation=Isolation.READ_COMMITTED)
def theMethod() {
}