假設我有兩個不同的線程T1和T2,它們同時訪問同一個數據庫並從同一個表中獲取數據。如何避免兩個不同的線程從數據庫讀取相同的行(Hibernate和Oracle 10g)
現在在線程啓動時,我需要從表中獲取數據並將行存儲到集合中,然後我將使用它們在別處執行某些工作。我不希望這兩個線程能夠處理相同的數據,因爲它會導致重複(和長時間)的工作。更具體地說,這是一個企業應用程序,需要在啓動時加載一些記錄並將其存儲在集合中以完成一些額外的工作。問題是在集羣環境中,這可能會導致兩個不同的實例加載相同的數據,因此工作可能會重複。所以我希望行只能由一個實例加載一次。
我該如何避免這種情況?
我目前使用Hibernate和Oracle 10g。這些是我的解決方案到現在:
以編程方式鎖定行。第一個讀取它會將一些「鎖定」列設置爲true,但如果第一個線程死亡而沒有將行設置爲「已處理」,很可能會發生死鎖。
使用悲觀鎖定。我嘗試使用LockMode.UPGRADE,但似乎沒有幫助,因爲我仍然能夠同時從兩個線程讀取數據。
public List<MyObject> getAllNtfFromDb() { Session session = HibernateUtil.getOraclesessionfactory().openSession(); Query q = session.createQuery( "from MyObject n where n.state = 'NEW'"); List<MyObject> list = (List<MyObject>) q.list(); for (int i=0; i<list.size(); i++) session.lock(list.get(i), LockMode.UPGRADE); return list; }
任何其他提示嗎?我究竟做錯了什麼?
謝謝。
也許你可以使用select for update語句? – soilworker 2015-01-15 17:09:29