這個問題的根源在於,什麼會導致失敗同步?這是一個通用的消息,只是意味着「出錯了」或會話本身有什麼問題嗎? 有一些類似標題的線程,但沒有一個似乎真正解決了爲什麼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())。