我正在使用 Grails 2.5.1,并且我有一个控制器调用一个服务方法,该方法偶尔会导致StaleObjectStateException
. 服务方法中的代码在obj.save()
调用周围有一个 try catch,它只是忽略了异常。但是,每当发生这些冲突之一时,日志中仍然会打印一个错误,并向客户端返回一个错误。
我的游戏控制器代码:
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)
}
}
}
我的游戏服务代码:
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 惰性集合的目的。如果我想自己管理所有的协会,我会的。
我已阅读有关悲观和乐观锁定的文档,但我的代码遵循那里的示例。
我想了解更多关于 Grails (GORM) 如何/何时检查陈旧性以及在哪里处理它的信息?