我遇到了一個問題。我有一個Hibernate應用程序,它將XML文件中的數據加載到併發模式的表中。某些部分數據可能相同,可能從不同的線程插入。每個線程都在自己的長時間交易中工作。有兩個或更多步驟嘗試提交事務時存在問題。例如兩個線程插入記錄到表城市,其中有名稱字段的限制。這意味着在flush()或commit()上發生ConstraintViolationException。我想自動處理這些衝突,並希望用舊的已插入對象替換新的問題對象。這可能嗎?我在Hibernate中查看saveOrUpdate()和樂觀版本控制。Hibernate併發插入
回答
我假設你使用MVCC-based DBMS之一。
如果事務隔離級別不高於READ COMMITTED,可以通過在插入新行之前發出一個查詢來檢查是否存在具有相同name
的城市的查詢來降低衝突概率。
請注意,saveOrUpdate()
不能幫助這裏,因爲name
不是主鍵。還要注意,根本不能防止衝突(至少不使用某些DBMS特有的功能),因爲基本上它是write skew anomaly的示例,這在基於MVCC的DBMS中無法防止。另外,如果導入XML文件的原子性並不重要,則可以將長事務分解成幾個較短的事務,並且在違反約束的情況下簡單地重試它們。
謝謝,分解交易是一個好主意。我認爲,在併發情況下,城市對象的存在並不能起作用。總會有碰撞的機會。同意saveOrUpdate()已經檢查過它。 – 2011-05-17 13:50:39
對不起,您的意思是使用READ UNCOMMITTED並檢查存在?我認爲它可以幫助。至少未被記錄的記錄是在交易中共享的,並且在沒有記錄的會話中進行存在檢查並不昂貴。 – 2011-05-17 14:10:37
在這樣的情況下,我們使用'insertOrUpdate()'方法的約定和下面的一般流程。該交易是在返回時由'insertOrUpdate()'方法的調用者承諾的:
public MyHibernateObject insertOrUpdate(MyHibernateObject newObj, Session s) {
String name = newObj.getCityName();
MyHibernateObject existingObj = getByCityName(name, s);
if (existingObj == null) {
s.saveOrUpdate(newObj);
return newObj;
} else {
existing.copyImportantFields(newObj);
s.saveOrUpdate(existing);
return existing;
}
}
- 1. Hibernate +併發插入(MySQL INSERT IGNORE)
- 2. hibernate插入?
- 3. hibernate @ManyToMany刪除並重新插入
- 4. Hibernate樂觀鎖定用於併發插入 - 可能嗎?
- 5. Web表單插入並觸發插入
- 6. SQL Server 2012併發插入
- 7. 在MySQL中併發插入?
- 8. 古典ASP併發插入
- 9. 併發插入流星
- 10. sqlite併發批量插入
- 11. hibernate nativesqlquery批量插入
- 12. 批量插入/使用Hibernate
- 13. hibernate createSQLQuery批量插入
- 14. Hibernate QueryDsl插入語句
- 15. 異常hibernate插入語句
- 16. Hibernate的批量插入
- 17. Grails/Hibernate批量插入
- 18. Spring中的Hibernate併發性
- 19. Hibernate中的併發事務
- 20. 在高併發使用Hibernate
- 21. hibernate和sqlserver併發問題?
- 22. MySQL併發多行插入 - 插入ID假設
- 23. 如何忽略hibernate錯誤並繼續插入數據?
- 24. 併發插入到實體集合
- 25. 防止在sql中併發插入
- 26. MySQL的交易和併發插入
- 27. sql觸發器更新並插入
- 28. SQL Server插入鎖與併發事務
- 29. Mysql的併發插入和鎖定
- 30. 合併與選擇插入觸發器
您好,如果您將問題分享給您的解決方案,我會很高興。看起來下面是正確的答案,但簡單的解釋應該更方便。非常感謝。 – Javatar 2012-02-25 18:04:19