У меня есть сценарий, когда объект обновляется двумя разными потоками. Ниже приведен код в классе сервиса grails. Я могу поймать исключение StaleObject, но когда я пытаюсь извлечь его из базы данных и повторить попытку, сохраняя значение, оно не работает.Обработка StaleObjectException в службе
public long updateTimer(Long timeLeft, TestAttempted testAttempted){
// Let's say testAttempted.version() is now 5
// It is concurrently updated by other thread, version is now 6
........
............
testAttempted.setTimer(someCalculatedValue)
try{
testAttempted.save(failOnError: true,flush:true) // StaleObject exception occurs
}catch(OptimisticLockingFailureException e){
testAttempted.refresh()
testAttempted.setTimer(someCalculatedValue)
testAttempted.save(failOnError:true)
}
}
Почему приведенный выше код не обновляет/не сохраняет значение в блоке catch? Я также попробовал метод TestAttempted.get (id) для извлечения последнего из базы данных, но он не работает.
Но когда я пытаюсь это обновляет последнее значение таймера:
В контроллере: -
try{
timeLeft = assessmentService.updateTimer(timeLeft,testAttempted)
}catch(OptimisticLockingFailureException e){
testAttempted = TestAttempted.get(session['testAttemptedId'])
........
testAttempted.setTimer(someCalculatedValue)
testAttempted.save(failOnError: true)
}
В службе:
public long updateTimer(Long timeLeft, TestAttempted testAttempted){
........
.................
testAttempted.setTimer(someValue)
testAttempted.save(failOnError: true)
return timeLeft
}
Это не работает, если она брошена и обрабатываются как в контроллере/службе. Он работает, когда его бросают в эксплуатацию и обрабатывают в контроллере. Как это возможно ?
Спасибо за ответ. На самом деле оба потока обновляют разные поля. Они никогда не обновляют общее поле. Поэтому я думаю, что падение поля версии должно быть более подходящим. Не так ли? –
Если у вас нет другого кода, который также обновляет этот Домен и полагается на оптимистичную блокировку, тогда да - просто отключите управление версиями для домена. – Yaro