我有一個場景,當一個對象被2個不同線程更新時。以下是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