2017-12-02 214 views
1

我試圖理解READ COMMITED和READ UNCOMMITED隔離級別在Hibernate中的工作方式,需要一些解釋。如何獲取共享和排他鎖在休眠

有2個線程THR1THR2兩者執行相同的事務方法(春季Transactional註釋與設置爲READ COMMITED隔離級別)。創建名稱交易爲這些線程TRA1TRA2相應地。該交易方法如下所示:

public void updateOrSavePreference(String name, String value) { 
    Preference preferenceToUpdate = findPreferenceUsingNamedQuery(name); // line 1. shared read lock acquired (uses HibernateTemplate.findByNamedQueryAndNamedParam(...)) 
    if (preferenceToUpdate != null) { // line 2. 
    preferenceToUpdate.setValue(value); // line 3. exclusive write lock acquired (actually I use the HibernateTemplate.merge(...) method 
             // instead a setter because the entity type is immutable, but it seems irrelevant for this example) 
    } else { // line 4. 
    HibernateTemplate.save(preferenceToUpdate); // line 5. exclusive write lock acquired 
    } 
} 

的優先級與Entity(optimisticLock = OptimisticLockType.NONE)註釋執行2PL模型爲這個實體(我錯了?)。我使用Oracle數據庫。

考慮以下方案:

  1. 讓我們假設線程THR1步驟1號線和查詢的對象。如果我理解正確,則此線程創建的事務TRA1將爲查詢的entiry獲取共享讀鎖。那麼,如果THR2線程步入第3行,試圖獲取該實體的獨佔寫入鎖定,則不應阻止THR2,直到TRA1釋放讀取鎖定爲止?

  2. 我們假設線程THR1進入第3行並獲得一個實體的獨佔寫入鎖定(獨佔鎖定一直持續到TRA1 transaction completes)。然後,THR2線程步入第1行並嘗試查詢此實體。不應該阻止THR2,因爲TRA2事務嘗試獲取讀鎖而其他事務TRA1爲此實體保存獨佔寫鎖定?

  3. 如果我從第2點複製READ UNCOMMITED隔離級別的場景,則執行TRA2事務的THR2不會看到TRA1事務中由THR1所做的更改,即使在refreshing或再次查詢實體後(「評估表達式」在調試下)。爲什麼?

回答

1

通過設置讀鎖,可以實現技術上的讀提交。但不一定。如果你的DBMS支持MVCC,你總是讀取提交的數據(除了你自己的事務中更改的內容)而不設置鎖定。

所以我懷疑你使用oracle,mysql(INNODB)或postgres做你的測試?所有這些DBMS都默認支持MVCC,所以它們從不設置共享讀鎖。

由於您正在使用Oracle「MVCC」數據庫,因此即使您在您的實體上配置了2PL協議,也不會實現2PL協議。如果你想找出真正的在本地陳述你的DBMS做到了激活本地語句的輸出,你可以在persistence.xml中做到:

<property name="hibernate.show_sql" value="true" /> 

也許你也應該看看transaction-isolation-levels-relation-with-locks-on-table 或第一個在:locks and oracle

+0

我忘了提到Preference類用實體(optimisticLock = OptimisticLockType.NONE)進行了註釋,我懷疑它會爲給定的實體強制執行2PL模型。我錯了嗎? – pbartosz

+0

是的,我使用Oracle數據庫。 – pbartosz