[轉帖]Mysql數據庫的事務特性、隔離級別及MVCC多版本併發控制簡介

https://my.oschina.net/tongchengyu/blog/4714950

事務的特性

數據庫如果支持事務,就要滿足下面四個特性(ACID)。

原子性(A:Atomicity)

在一個事務中,多個sql操作,要麼一起成功(所有數據操作都成功),要麼一起回滾(其中一個沒有成功,其他數據操作一起恢復到開始狀態)。

一致性(C:Consistency)

數據修改前是準確的,修改後也要說準確的。指的是數據從一個一致性狀態,轉換到另一種一致性的狀態。(例如:A和B總共有10個蘋果,A轉讓了幾個蘋果給B,事務結束後,A和B總共還是10個蘋果)。

隔離性(I:Isolation)

當數據庫有多個事務一起執行時,各個事務之間互相不影響,每個事務感知不到有其他的事務在執行。

持久性(D:Durability)

數據庫事務結束提交後,數據修改永久有效,即使數據庫重啓,遇到其他問題關掉,再打開後,之前提交過的數據的修改還是生效的(例如:程序執行數據的操作,事務提交後,突然數據庫服務器斷電等原因導致數據庫停掉不可用,恢復後,數據還是修改後的狀態)。

事務隔離級別

讀未提交

兩個事務同時操作數據庫,其中一個事物修改數據庫後,沒有提交,另一個事物可以讀取到修改過的數據。

讀已提交

有兩個事務,第一個事務查詢一條數據,第二個事務修改這條數據提交後,第一個事務又查詢該數據,第一個事務前後兩次查詢的結果不一致。

可重複讀(mysql默認隔離級別,通過MVCC<Mutil-Version Concurrency Control>機制實現)

有兩個事務,第一個事務查詢一條數據,第二個事務修改這條數據提交後(出於性能考慮,使用了以樂觀鎖爲理論基礎的MVCC<多版本併發控制>來實現),第一個事務又查詢該數據,第一個事務前後兩次查詢的結果不致。

串行化(解決 幻讀 的問題)

可重複讀可以限制兩個事務併發修改刪除數據導致前後查詢不一致的情況,但是無法限制insert(行鎖只能鎖住行,新增數據無法限制)。

幻讀的案例場景:有兩個事務,第一個數據查詢列表數據條數,第二個事務新增數據到表中並提交事務,第一個事務又重新查詢數據條數,第一個事務前後兩次查詢的數據不一致。

串行化:有兩個事務,第一個事務查詢數據,第二個事務新增數據到表中,會報錯(表級鎖),不能插入數據,第一個事務再查詢數據,前後兩次結果一致。串行化併發低。

MVCC原理簡介:

通過事務id控制不同版本數據(因爲通過事務id控制數據,所以下面數據中id也是會重複的),sql查詢的時候,後兩列隱藏列不會顯示。下列表格對應的事務開始順序與數字大小順序一致,最終所有事務一起結束。(通過併發情況簡單說明MVCC原理)

事務id=1插入數據;事務id=3插入數據;事務id=4刪除數據;事務id=5修改數據;表最終數據如下:

id 數據 更新事務ID(隱藏列) 刪除事務ID(隱藏列)
1 張三 1 4
2 小明 1
3 李四 1
4 王五 3
2 小明111 5

事務id=2,查詢全表數據,查詢數據如下:

start transaction; 

select * from a; //(1) 

select * from a; //(2) 

commit; 

假設:

事務id=2中(1)查詢發生在事務id=1之後 ;

事務id=2中(2)查詢發生在事務id=3插入數據之後;

事務id=2兩次查詢結果都一樣(通過事務id做了限制,只會查詢小於等於當前事務id的數據)

id 數據 更新事務ID(隱藏列) 刪除事務ID(隱藏列)
1 張三 1
2 小明 1
3 李四 1

假設:

事務id=2中(1)查詢發生在事務id=1之後 ;

事務id=2中(2)查詢發生在事務id=4刪除數據之後;

事務id=2兩次查詢結果都一樣(通過事務id做了限制,只會查詢小於等於當前事務id的數據)

id 數據 更新事務ID(隱藏列) 刪除事務ID(隱藏列)
1 張三 1 4
2 小明 1
3 李四 1

假設:

事務id=2中(1)查詢發生在事務id=1之後 ;

事務id=2中(2)查詢發生在事務id=5修改數據之後(修改也相當於插入一條數據,數據的事務id是不同的);

事務id=2兩次查詢結果都一樣(通過事務id做了限制,只會查詢小於等於當前事務id的數據)

id 數據 更新事務ID(隱藏列) 刪除事務ID(隱藏列)
1 張三 1
2 小明 1
3 李四 1
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章