1. 程式人生 > 其它 >MySql MVCC是如何實現的-事務隔離級別?

MySql MVCC是如何實現的-事務隔離級別?

事務就是要保證一組資料庫操作,要麼全部成功,要麼全部失敗。
在MySql中,事務支援是在引擎層實現的,但是隻有InnoDB支援事務,MyISAM是不支援的。
事務具有原子性,一致性,隔離性,永續性,這裡我們要談的就是隔離性。
MySql標準的事務隔離級別包括:
讀未提交(read uncomminted):一個事務還沒有提交時,它做的變更就能被被的事務看到。
讀提交(read commited):一個事務提交後,它做的變更才會被其他事務看到。
可重複讀(repeatable read):一個事務執行過程中看到的資料,總是跟這個事務在啟動時看到的資料是一致的。
序列化(serializable)

:對於同一行記錄,“寫”會加“寫鎖”,“讀”會加“讀鎖”,出現讀寫鎖衝突的時候,後訪問的食物必須等待前一個事務執行完成,才能繼續執行。

事務隔離級別 髒讀 不可重複讀 幻讀
讀未提交
不可重複讀
可重複讀
序列化

1.檢視MySql預設的隔離級別,可見MySql預設可重複讀。從上圖我們可以看到,不管是什麼隔離級別,都會存在一些問題,並且隔離的越嚴實,執行效率就會越低。比如:序列化,所以很多時候我們只是在效率和隔離之間找一個平衡點。

MySql5.7以前的版本:show variables like 'tx_isolation';
MySql5.7(包含)以後的版本:show variables like 'transaction_isolation';

mysql> show variables like 'tx_isolation';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| tx_isolation | REPEATABLE-READ |
+---------------+-----------------+
1 row in set (0.00 sec)

舉例說明:

事務A 事務B
1啟動事務
2.查詢得到值V0 3啟動事務
4.查詢得到值V0
5.將V0改為V0+1
6.查詢得到值V1
7.提交事務B
8.查詢得到值V2
9.提交事務A
10.查詢得到值V3

1.讀未提交

  • 將會話的隔離級別設定為讀未提交,終端1和終端2一起設定
set session transaction isolation level read uncommitted;
  • 按照上述表格中的順序,依次執行,得到V0=1,V1=2,V2=2,V3=2

注意步驟6直接讀到了步驟5中修改的值,此時事務B實際還未提交,這就是讀未提交(read uncommited),事務級別讀未提交存在髒讀的問題,比如此用例中如果事務B做了回滾,那麼事務A在第4步驟查詢得到的值就是不正確的,這就是所謂的髒讀

2.讀提交

  • 將會話的隔離級別設定為讀提交,終端1和終端2一起設定
set session transaction isolation level read committed;
  • 按照上述表格中的順序,依次執行,得到V0=2,V1=2,V2=3,V3=3

注意步驟6沒有讀到步驟5中修改的值,步驟7,事務B提交之後,步驟8讀到了步驟5修改的值,這就是讀提交(read commited),事務級別讀提交存在不可重複讀的問題,比如此用例中,同一個事務,在不同的階段讀同一行資料讀到了不同的值,這就是所謂的不可重複讀,解決不可重複讀的方法是加行鎖,事務A在執行未提交的時候,事務B無法修改資料,即可避免

3.可重複讀

  • 將會話的隔離級別設定為可重複讀,終端1和終端2一起設定
set session transaction isolation level repeatable read;
  • 按照上述表格中的順序,依次執行,得到V0=3,V1=3,V2=3,V3=4

注意步驟6沒有讀到步驟5中更改的值,步驟7事務B提交之後,步驟8依然沒有讀到步驟5中更改的值,直到事務A也提交之後才讀到事務B更改的值,這就是可重複讀(repeatable read)

  • 事務級別可重複讀存在幻讀的問題
事務A 事務B
1啟動事務
2查詢V0
3插入
4查詢V1
5提交事務
6查詢V2
7更新
8查詢V3
  • 按照上述表格的順序,依次執行,V0=V1=V2=5行,V3=6行,也就是在事務A中查到事務B插入的資料,這就是所謂的幻讀,解決幻讀的方法是加表鎖,事務A在執行未提交的時候,事務B無法插入資料,即可避免

4.序列化

  • 將會話的隔離級別設定為序列化,終端1和終端2一起設定
set session transaction isolation level serializable;
事務A 事務B
1啟動事務
2啟動事務
3插入資料
4查詢資料
5提交事務
6查詢資料

按照上述表格的順序,依次執行,步驟3插入資料,但是未提交的時候,步驟4出現了獲取鎖超時的情況,這就是序列化(serializable
,同一行資料不允許併發執行,在寫時,讀必須等待。

牛人之所以是牛人,是因為你現在在踩的坑,他曾經都已經踩過了。