4

Grailsのupdateアクションは、最初に更新するオブジェクトのバージョンをチェックしてから、それを更新します。Grailsのどの部分が、バージョンの確認とオブジェクトの更新中に別のリクエストによってオブジェクトが更新されないようにしますか?

アップデート:

はい、hibernateはオブジェクトを保護するときにバージョンをチェックし、楽観的ロックが失敗した場合に例外をスローします。そして、休止状態はcheck + updateがアトミックであることを確認すると思いますが、...

grailsで生成されたupdateメソッドを見ると、grailsが最初にダブルチェックし、次に(私の観点から)例外を処理する準備ができていないことがわかります。updateメソッドが正しいバージョンをすでにチェックした後に休止状態が例外をスローする可能性はわずかですが、私には可能であるように思われます。

では、保存を試みて例外をキャッチするだけで十分ではないでしょうか(存在する場合)。

4

1 に答える 1

4

Hibernateレイヤーによって管理されます。これは「楽観的ロック」と呼ばれ、基本的には既知のバージョンのオブジェクトのみを更新します。好き:

UPDATE SET
  %... fields ...%, 
  version = version + 1                      --update version to a new value
WHERE 
  id = %obj id%                              --current object
  AND version = %previous obj version%`      --last known version 

そして、更新に失敗したときに例外をスローします(ところで、現時点では、このエラーから回復するのは困難です。ほとんどの場合、更新を失うだけです)。

データが確実に保存されるようにする場合は、データを強制的に保存してみてください(保存/検証エラーを確認してください)。

try {
    if (!obj.save(flush: true)) {
        // validation error
    }
} catch (OptimisticLockingFailureException e) {
    // not saved
}

または、更新前にデータをロックすることもできます。同時更新が多い場合にのみ役立ちます。

MyDomain obj = MyDomain.lock(params.id) //now it's locked for update
// update fields
obj.save()

GORMロックの詳細については、 http: //grails.org/doc/latest/guide/GORM.html#lockingを参照してください。

于 2012-05-23T05:48:28.930 に答える