java lock JPA中的PESSIMISTIC_READ和PESSIMISTIC_WRITE有什麼區別?



jpa pessimistic lock example (4)

我已經閱讀了Java Persistence 2.0中的文章Locking and Concurrency ,並運行了示例應用程序。 但我仍然無法意識到PESSIMISTIC_READ和PESSIMISTIC_WRITE之間的區別。 我試圖修改代碼,並且使用PESSIMISTIC_READ和PESSIMISTIC_WRITE的代碼將具有與“for update”調用sql相同的結果。


Answer #1

規範允許JPA實現為每個實現使用不同類型的數據庫鎖。 大多數數據庫只有一種類型的聲明性鎖,因此在大多數實現中,兩者是相同的(沒有區別)。


Answer #2

不同之處在於鎖定機制。

PESSIMISTIC_READ鎖定意味著當您有這樣的鎖定時,臟讀和不可重複的讀取是不可能的。 如果要更改數據,則需要獲取PESSIMISTIC_WRITE

PESSIMISTIC_WRITE鎖定保證除了臟的和不可重複的讀取是不可能的,您可以在不獲得額外鎖定的情況下更新數據(並且在等待獨占鎖定時可能出現deadlocks )。

╔══════════════════════╦══════════════════════════╦══════════════════════════╗
║     LockModeType     ║     PESSIMISTIC_READ     ║    PESSIMISTIC_WRITE     ║
╠══════════════════════╬══════════════════════════╬══════════════════════════╣ 
║         type         ║       SHARED LOCK        ║      EXCLUSIVE LOCK      ║
╠══════════════════════╬══════════════════════════╬══════════════════════════╣   
║  isReadOnly without  ║                          ║                          ║
║   additional locks   ║            YES           ║            NO            ║
╠══════════════════════╬══════════════════════════╬══════════════════════════╣
║      dirty reads     ║            NO            ║            NO            ║
╠══════════════════════╬══════════════════════════╬══════════════════════════╣
║ non-repeatable reads ║            NO            ║            NO            ║
╠══════════════════════╬══════════════════════════╬══════════════════════════╣
║ how to update data   ║ obtain PESSIMISTIC_WRITE ║         ALLOWED          ║
╠══════════════════════╬══════════════════════════╬══════════════════════════╣
║                      ║       no one holds       ║      no one holds        ║
║ how to obtain lock   ║     PESSIMISTIC_WRITE    ║   PESSIMISTIC_READ   or  ║
║                      ║                          ║   PESSIMISTIC_WRITE      ║
╠══════════════════════╬══════════════════════════╬══════════════════════════╣
║                      ║                          ║   when there is a high   ║
║                      ║  you want to ensure no   ║ likelihood of deadlock or║
║      when to use     ║ dirty or non-repeatable  ║   update failure among   ║ 
║                      ║   reads are possible     ║    concurrent updating   ║
║                      ║                          ║       transactions       ║
╚══════════════════════╩══════════════════════════╩══════════════════════════╝

資源:

JPA 2.1


Answer #3

PESSIMISTIC_READ獲取關聯表行記錄上的共享(讀取)鎖定,而PESSIMISTIC_WRITE獲取獨占(寫入)鎖定。

共享鎖會阻止任何其他並發獨占鎖請求,但它允許其他共享鎖請求繼續。

獨占鎖會阻止共享和獨占鎖定請求。

值得一提的是,對於Hibernate,如果數據庫不支持共享鎖(例如Oracle),那麼共享鎖請求( PESSIMISTIC_READ )將只獲取一個獨占鎖請求( PESSIMISTIC_WRITE )。

有關更多詳細信息,請查看有關鎖的 本文以及有關JPA悲觀鎖類型的本文


Answer #4

一個是讀鎖定,另一個是寫鎖定,或者分別在讀取或更新期間。

FTA:

  • PESSIMISTIC_READ。 實體管理器在事務讀取後立即鎖定實體。 鎖定一直持續到事務完成。 當您想使用可重複讀取語義查詢數據時,將使用此鎖定模式。 換句話說,您希望確保在連續讀取之間不更新數據。 此鎖定模式不會阻止其他事務讀取數據。

    PESSIMISTIC_WRITE。 一旦事務更新實體管理器,實體管理器就會鎖定該實體。 此鎖定模式強制嘗試更新實體數據的事務之間的序列化。 當並發更新事務中存在更新失敗的可能性高時,通常使用此鎖定模式。





pessimistic