我正在閱讀不同的事務隔離級別,並且跨越了SERIALIZABLE
隔離級別。我也知道像Postgres,Oracle和MySQL這樣的數據庫支持SELECT .. FOR UPDATE
語法。可序列化事務vs SELECT FOR UPDATE
但是,當我想鎖定希望執行更新的行(或一系列行)時,我應該如何使用這些應用程序。
以前使用JPA時,我總是在查詢中使用@Transactional
加上LockModeType.PESSIMISTIC_WRITE
。這轉換爲在SQL中使用READ_COMMITTED
隔離級別與SELECT .. FOR UPDATE
。
但現在,已經瞭解SERIALIZABLE
,我想知道如果我用@Transactional(isolation=SERIALIZABLE)
與正常SELECT
(如em.findById獲取分離實體),接着是UPDATE
(合併的會有什麼不同實體)。
行爲是一樣的嗎?
舉例說,我有一個銀行系統,我希望在兩個賬戶之間轉賬。在轉移過程中,我需要這些賬戶不被幹涉。所以,假設我用-100借記一個帳戶並將其記入另一個帳戶。確保這些帳戶僅適用於執行更新的交易的最佳方法是什麼?
假設我正在操作JPA分離的實體,因此在更新之前,我將不得不從數據庫中讀取它們,例如, findById()。
- 使用
@Transactional(isolation=READ_COMMITTED)
,em.findById與LockModeType.PESSIMISTIC_WRITE
(即SELECT .. FOR UPDATE
),然後em.merge(即UPDATE
)? - 或使用
@Transactional(isolation=SERIALIZABLE)
,em.findById,然後em.merge(即UPDATE
)?
「*與SERIALIZABLE一切都始終鎖定*」作爲一般性陳述並非如此。這在很大程度上取決於DBMS的實現(例如Postgres沒有這樣做) –
這是真的「PostgreSQL例如不會這樣做」在可序列化的PostgreSQL中將執行所有沒有Lock的選擇語句,但是當發生併發時寫入語句最後一個事務獲得授予序列化完整性失敗 – deFreitas