私は Grails 2.5.1 を使用しています。サービス メソッドを呼び出すコントローラーがあり、StaleObjectStateException
. サービス メソッドのコードにobj.save()
は、例外を無視するだけの呼び出しの周りに try キャッチがあります。ただし、これらの競合のいずれかが発生するたびに、ログにエラーが出力され、クライアントにエラーが返されます。
私の GameController コード:
def finish(String gameId) {
def model = [:]
Game game = gameService.findById(gameId)
// some other work
// this line is where the exception points to - NOT a line in GameService:
model.game = GameSummaryView.fromGame(gameService.scoreGame(game))
withFormat {
json {
render(model as JSON)
}
}
}
私の GameService コード:
Game scoreGame(Game game) {
game.rounds.each { Round round ->
// some other work
try {
scoreRound(round)
if (round.save()) {
updated = true
}
} catch (StaleObjectStateException ignore) {
// ignore and retry
}
}
}
スタック トレースは、私のメソッドから例外が生成されたことを示しGameController.finish
ていますが、それは私のメソッド内のコードを指していませんGameService.scoreGame
。これは、オブジェクトの保存/更新が試行されたときではなく、トランザクションが開始されたときに Grails が古さをチェックすることを意味しますか?
私はこの例外に何度も遭遇しましたが、通常はオブジェクト グラフをトラバースしないことで修正します。
たとえば、この場合、game.rounds
参照を削除して次のように置き換えます。
def rounds = Round.findAllByGameId(game.id)
rounds.each {
// ....
}
しかし、それは、トランザクションが作成されたときに古さがチェックされないことを意味し、それは常に実用的であるとは限らず、私の意見では、Grails の遅延コレクションの目的を無効にします。すべての関連付けを自分で管理したい場合は、そうします。
Pessimistic and Optimistic Lockingに関するドキュメントを読みましたが、コードはそこの例に従います。
Grails (GORM) が古さをチェックする方法/タイミング、およびそれを処理する場所について詳しく知りたいですか?