事務的隔離級別: READ UNCOMMITTED(未提交讀) 在這個級別,事務中的修改,即使沒有提交,對其他事務也都是可見的,事務可以讀取未提交的數據。 READ COMMITTED(提交讀) 一個事務開始時,只能“看見”已經提交的事務所做的修改。也就是一個事務從開始知道提交前,所做的任何修改對其 ...
事務的隔離級別:
READ UNCOMMITTED(未提交讀)
在這個級別,事務中的修改,即使沒有提交,對其他事務也都是可見的,事務可以讀取未提交的數據。
READ COMMITTED(提交讀)
一個事務開始時,只能“看見”已經提交的事務所做的修改。也就是一個事務從開始知道提交前,所做的任何修改對其他事務都是不可見的
REPEATABLE READ(可重覆讀)
可重覆讀解決了“臟讀”的問題,但是有“幻讀”的問題,InnoDB和XtraDB存儲引擎通過MVCC解決了幻讀的問題。
SERIALIZABLE(可串列化)
最高的隔離級別,SERIALIZABLE會在讀取的每一行數據上都加鎖,所以可能導致大量的超時和鎖競爭的問題。
1. MySQL可以通過執行SET TRANSACTION ISOLATION LEVEL命令來設置隔離級別。新的隔離級別會在下一個事務開始的時候生效。
2. 也可以改變當前回話的隔離級別:SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
3. MySQL伺服器層不管理事務,事務是由下層存儲引擎實現的。
臟讀:
允許事務B讀到了事務A未提交的數據,可能就造成了臟讀,臟讀的本質就是無效的數據,只有當事務A回滾,那麼事務B讀到的數據才為臟數據,所以這裡只是可能造成臟讀。如果事務A不回滾,事務B讀到的數據就不為臟數據,也就是有效的數據。
不可重覆讀:
不可重覆讀是指在一個事務範圍中2次或者多次查詢同一數據M返回了不同的數據,例如:事務B讀取某一數據,事務A修改了該數據M並且提交,事務B又讀取該數據M(可能是再次校驗),在同一個事務B中,讀取同一個數據M的結果集不同,這個很蛋疼
幻讀:
當用戶讀取某一個範圍的數據行時,另一個事務又在該範圍內插入了新行,當用戶再讀取該範圍的數據行時,會發現會有新的“幻影行”,例如:事務B讀某一個數據M,事務A對數據M增加了一行並提交,事務B又讀數據M,發生多出了一行造成的結果不一致(如果行數相同,則是不可重覆讀)。
丟失更新:
事務A和事務B,同時獲得相同數據,然後在各自的事務中修改數據M,事務A先提交事務,數據M假如為M+,事務B後提交事務,數據M變成了M++,最終結果變成M++,覆蓋了事務A的更新。
隱式鎖定和顯式鎖定:
1.InnoDB採用的是兩階段鎖定協議(two-phase locking protocol)。在事務執行過程中,隨時都可以執行鎖定,鎖只有在執行COMMIT和ROLLBAK的時候才會釋放,並且所有的鎖是在同一時刻被釋放。
2. LOCK TABLES和事務之間相互影響的話,情況會變得非常複雜,所以除非事務中禁用了AUTOCOMMIT,可以使用LOCK TABLES之外,其他任何時候都不要顯示的執行LOCK TABLES,不管使用的是什麼存儲引擎。
死鎖:
兩個或多個事務在同一資源上相互占用,並請求鎖定對方占用的資源,從而導致惡性迴圈現象。當多個事務試圖以不同的順序鎖定資源時,就可能會產生死鎖。多個事務同時鎖定同一個資源也可能會產生死鎖
例如:
--事務1 START TRANSACTION; UPDATE price SET close=45.5 WHERE stock_id=4 AND date='2017-10-11'; UPDATE price SET close=19.8 WHERE stock_id=3 AND date='2017-10-12'; COMMIT; --事務2 START TRANSACTION; UPDATE price SET high=20.12 WHERE stock_id=3 AND data='2017-10-12'; UPDATE price SET high=47.20 WHERE stock_id=4 AND data='2017-10-11'; COMMIT;
如果湊巧,兩個事務都執行了第一條UPDATE 語句,更新了一行數據,同時也鎖定了該行數據,接著每個事務都嘗試去執行第二條UPDATE語句,卻發現改行已經被對方鎖定,然後兩個事務都等待對方釋放鎖,同時有持有對方需要的鎖,則陷入死迴圈。除非有外部因素接入才可能接觸死鎖。InnoDB目前處理死鎖的方法時,經持有最少行級排他鎖的事務進行回滾
InnoDB-MVCC多版本併發控制
參考:
[1] 《高性能MySQL》(第三版), Baron Schwartz等 著,寧海元等 譯,電子工業出版社 ,2013
[2] 博客,https://segmentfault.com/a/1190000004469395#articleHeader6