2012-10-18 62 views
0

這個問題的根源在於,什麼會導致失敗同步?這是一個通用的消息,只是意味着「出錯了」或會話本身有什麼問題嗎? 有一些類似標題的線程,但沒有一個似乎真正解決了爲什麼hibernate無法同步會話,這只是人們忽略的錯誤消息的一部分。Grails:獲取/解決「無法與會話同步數據庫狀態」?

我的具體情況/細節(雖然它是真正切對上述問題的):

在數據導入(20-120分鐘),我在做大量的處理。持續性不會開始,直到整個域對象集已經建立並經過驗證以保持一致性。在這段時間裏,我建立了大約200,000個域對象。在這個過程結束時,它會遍歷它們並將它們保存到數據庫中,並且(出於性能原因)在每50或100個對象之後刷新/清除會話。一旦持久性開始,域對象不會被更改。

這一切都發生在單個服務調用中,即單個事務。我也無法在我的測試系統上重現這一點,它只發生在生產中。

我使用domainObj.save()而非session.saveOrUpdate(domainObj),我唯一一次手動觸摸在所有會話沖洗/一組更新後的清洗它:

def session = sessionFactory.currentSession 
session.flush() 
session.clear() 

這就是異常被拋出的地方。

緊隨同步失敗的消息是(可能的結果,但也許事業相關):

Could not execute JDBC batch update; SQL [insert into domainB(field1, field2, etc) values (?, ?, ?)]; 
nested exception is org.hibernate.exception.ConstrainViolationException: Could not execute JDBC batch update 

我意識到這ConstrainViolation(是的,「約束」而不是「限制」)似乎是一個數據錯誤,但數據集一直在工作,並且不改變導入文件或代碼,就開始拋出這個錯誤。它也繼續在其他系統上工作,所以我排除了相對較爲確定的數據錯誤。

由於對象關係的性質,我幾乎肯定了相同的對象被多次保存。這是提高性能的另一個地方,但我認爲這是無關緊要的,因爲一旦對象被保存起來,它應該分配ID並重新保存,不應該導致錯誤。

在這一點上,我已經離題進入漫不經心和猜測,我不希望有人爲我解決我的問題,但希望有人明確地瞭解有關同步會話的內容,而不是「你確定你沒有插入重複的數據?「因爲我儘可能確定(使用約束唯一字段作爲查找要保存的域對象的鍵來遍歷Hashmap.keySet())。

回答

2

不幸的是,我仍然不知道如何實際調試「無法與會話同步數據庫狀態」,但我終於可以解決這個問題。

顯然,數據庫使用的Oracle表空間未設置爲增長,並且已經填滿。一旦表空間設置爲「可擴展」,此錯誤消失。我非常懷疑這會幫助其他人遇到相同的問題,因爲錯誤信息不適用,但是,你永遠不知道。