mysql事务隔离级别与锁_mysql事务隔离级别与锁
2.隔離級別實現
上一節介紹了ANSI定義的3種異象,及根據禁止異象的個數而定義的事務隔離級別。因為不存在嚴格、嚴謹的“官方”定義,各主流
2.1 Lock-based 隔離級別實現
在展示Lock-based隔離級別實現前,先介紹幾個與鎖相關的概念:Item Lock:對訪問行加鎖,可以防止dirty/fuzzy read。
Predicate Lock(gap lock):對search的范圍加鎖,全表掃描直接對整張表加鎖,可防止phantom read。
Short duration:語句結束后釋放鎖。
Long duration:事務提交或回滾后釋放鎖。
上述鎖操作組合,便可實現不同級別的事務隔離標準,如下表所示。
其中S lock代表共享鎖,X lock代表排它鎖。
首先所有寫操作加X locks時,都會選擇Long duration,否則short duration鎖被釋放后,在事務提交前該條更改可能被其它事務寫操作覆蓋,造成臟寫(dirty write)。
其次對于讀操作:
Short duration Item S lock 禁止了 P1發生,讀操作如果遇到正在修改的行(寫事務加了X Lock),阻塞在S Lock,直到寫事務提交。
Long duration Item S lock 禁止了P2發生,寫操作遇到讀事務(S Lock),阻塞在X Lock上直到讀事務提交或回滾。
Long duration Predicate/Table S Lock 禁止了P3發生,(范圍)寫操作遇到范圍讀操作(加Predicate S Lock),會被阻塞,直到讀事務提交或回滾。
基于鎖實現的三種隔離級別分別能禁止的異象如下表所示:
然而當今數據庫基于性能等多方面考慮,很少有完全基于鎖實現隔離級別的,MVCC+Lock的方式,可以滿足讀請求不加鎖,是主流的實現方式。
2.2 Oracle隔離級別的實現
Oracle僅支持兩種隔離級別:Read Committed與Serializable。盡管官方這樣描述,Oracle的Serializable實際是基于MVCC+Lock based的SI(Snapshot Isolation)隔離級別。
為實現快照讀,內部維護了全局變量SCN(System Commit/Change Number),在事務提交時遞增。讀請求獲取Snapshot便是獲取當前最新的SCN。Oracle實現MVCC的方式是將block分為兩類:(1)Current blocks為當前最新的頁面,與持久化態數據保持一致。(2)Consistent Read blocks,根據snapshot SCN生成相應的一致性版本頁面。
以下兩個具體的例子展示了:不同隔離級別下,讀寫語句在數據庫內部發生了什么。
Oracle在read committed隔離級別下,每條語句都會獲取最新的snapshot,讀請求全部是snapshot讀。寫請求在更新行之前,需要加行鎖。由于寫操作不會因為有其它事務更新了同一行,而停止更新(除非不滿足更新的謂詞條件了),因此Lost Update有可能發生。
Oracle在serializable隔離級別下,事務開始便獲取snapshot。讀請求全部是snapshot讀,而寫請求在更新行之前,需要加行鎖。寫操作在加鎖后,首先檢查該行,如果發現:最近修改過這行的事務的SCN大于本事務的SCN,說明它已經被修改且無法被本事務看到,會做報錯處理,避免了Lost Update。這種寫沖突的實現,顯然是first committer wins。
下表展示了Oracle的兩種隔離級別,分別能夠避免哪些異象:
2.3
InnoDB同樣以MVCC+Lock的方式實現隔離級別。其中普通select語句均是snapshot read。而delete/update/select for update等語句是加鎖實現的current read,如下表所示(注:該表為Pecona 5.6版本的代碼實現)。
InnoDB的RC隔離級別的表現與Oracle相似。而相較于Oracle的SI,InnoDB RR隔離級別依舊不能避免Lost Update(例如下例)。究其原因,InnoDB在RR隔離級別下,不會在事務提交時判斷是否有其它事務修改過該行。這避免了了SI更新沖突帶來的回滾代價,帶來了可能發生Lost Update的風險。
由于update等操作均是加鎖的當前讀,因此Phantom Read的現象也是存在的(如下表所示)。但是如果將Txn1的update語句替換為select語句,Phantom Read現象則可以禁止,因為整個事務select語句使用的是同一個snapshot。
Innodb RR的實現方式雖然并非并未嚴格排除Lost Update和Repeatable Read,但其充分利用MVCC讀不加鎖的并發能力,同時current read避免了SI在更新沖突劇增時過多的回滾代價。
InnoDB還實現了Lock Based Serializable(詳見2.1),禁止了所有異象。
總結
以上是生活随笔為你收集整理的mysql事务隔离级别与锁_mysql事务隔离级别与锁的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql键1键2_详解mysql基本操
- 下一篇: aspx mysql类_aspx中的my