我的Grails應用程序有一個服務方法,它可以更新last.fm的web服務中的藝術家列表。Grails編程事務處理
@Transactional(propagation = Propagation.NOT_SUPPORTED)
void updateLastFmArtists(Range idRange = null) {
Artist.list().each { Artist artist ->
// We could be updating a lot of artists here, the process could take up
// to an hour and we don't want to wrap all that in a single transaction
Artist.withTransaction { status ->
try {
updateArtistInfo(artist)
} catch (IOException ex) {
status.setRollbackOnly()
}
}
}
}
每個個體藝術家它自己的事務,如果IOException
拋出應當回滾內更新。不過,我注意到以下行爲:
如果要更新一個藝術家試圖拋出一個IOException
- 導致事務回滾 - 那麼接下來藝術家的更新總是失敗,因爲以下錯誤
org.hibernate.LazyInitializationException:無法初始化懶洋洋地一 角色的集合:org.example.Artist.topTracks,沒有會話或 會話關閉
如果我改變上面的代碼,使每一位藝術家被更新w^ithin它自己的會話,這似乎是解決問題,
Artist.withNewSession { session ->
Artist.withTransaction { status ->
try {
updateArtistInfo(artist)
} catch (IOException ex) {
status.setRollbackOnly()
}
}
}
但我不明白爲什麼我要做到這一點,即這是爲什麼回滾事務似乎關閉會話?
+1但是,在這種特殊情況下,它不是一個無法解決的異常,這是我在單個事務範圍內捕捉的一個例外。我覺得這很令人吃驚,這會使整個會話無效 –
我增加了一些對此的引用,基於文檔的建議是重新開始新會話,因爲會話的某些方法不會使會話保持一致狀態在回滾的情況下 –
感謝您的幫助,但是,上面的引用是關於Hibernate或Hibernate異常拋出的異常,但我的情況並不涉及這兩種異常。我猜這是我對'status.setRollbackOnly()'的調用,它會使會話失效而不是拋出的異常 –