事務隔離級別

背景

對於軟件開發人員來說,有時候我們需要面對瞬時海量的併發請求,例如阿里雙十一等活動,當處理併發流程時需要我們通過各種機制保持數據一致性,其中,最有效的一種機制就是鎖機制。而對於數據庫管理人員來說,併發問題同樣存在。併發問題的本質在於一條邏輯代碼在機器層面可能需要幾條指令來完成,也就是說這條邏輯代碼可能在多個機器週期內完成,如果在順時執行時這樣執行是不會存在問題的,而在併發執行時就會出現數據不一致的情況。這種最小的邏輯指令對應到數據庫中就是事務,事務包含原子性(Atomicity)、一致性(Consistency)、一致性(Consistency)和持久性(Durability)。而由於一個事務在機器層面可能需要幾條指令完成,這也意味着它在併發時會出現如下問題:髒讀、不可重複讀和幻讀,下面以MySQL爲例詳細介紹在什麼情況下可能會出現上述問題。

## Read uncommitted(讀未提交)

此事務隔離級別會出現**髒讀現象***(事務的修改,即使沒有提交,其他事務也能看的到),不建議在生產環境中去使用。

實驗-> 髒讀現象
  • 查看隔離級別

show variables like 'tx_iso%';
  • 修改隔離級別

mysql> set tx_isolation='READ-UNCOMMITTED';

注意:READ-UNCOMMITTED是字符串,如果不使用雙引號,就會報錯,錯誤信息如下:


 set tx_isolation=READ-UNCOMMITTED;

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'READ-UNCOMMITTED' at line 1
  • 創建表

create table test(int id);//典型的錯誤,可以和java 類比

create table test(id int);//正確寫法
  • session1中新增一條數據,但是沒有提交,可以session2卻可以查詢到session這條最新數據

image.png

注意:我們需要手動開啓事務(begin)和提交事務(commit),不然MySQL會自動提交事務

Read committed(讀已提交)

針對當前讀,RC隔離級別保證對讀取到的記錄加鎖(記錄鎖),存在不可重複讀現象(在一個事務內,多次讀取,會讀取到不同的數據)。

實驗-> 不可重複讀現象
  • 清除test數據

truncate table test;

image.png
我們發現session2中執行兩次select * from test會出現不同的結果,這就是不可重複讀現象。

##Repeatable read(可重複讀)

這是MySQL默認隔離級別,解決不可重複讀,但是還會出現存在幻讀現象。幻讀現象就是說當某個會話對某個數據進行修改並提交,而其他會話讀取這個數據並不是最新的值。

實驗-> 可重複讀

session1        session2

begin;             begin;

                       select ;//獲得一個時間點快照,在表記錄中的每一個行都會有trx_id,以後每次查詢,都會查詢比這個trx_id小於等於的值

insert;

commit;

                        select;

MySQL通過MVCC(解決讀寫併發問題)和間隙鎖(解決寫寫併發問題)來解決幻讀,Repetable Read違反了隔離性,ACID中對隔離性的定義如下:


The isolation property ensures that the concurrent execution of transactions results in a system state that would be obtained if transactions were executed sequentially, i.e., one after the other. Providing isolation is the main goal of concurrency control. Depending on the concurrency control method (i.e., if it uses strict - as opposed to relaxed - serializability), the effects of an incomplete transaction might not even be visible to another transaction

大概意思:一個沒有提交的事務對其他事務是不可見的,而提交過的事務對其他事務是可見的。但是Repeatable Read中提交的事務對其他事務是不可見的,顯然違反了隔離性。

## Serializable(串行化)

串行化解決了髒讀、不可重複讀、幻讀現象,但是效率會比較低下。從MVCC併發控制退化爲基於鎖的併發控制。不區分快照讀與當前讀,所有的讀操作均爲當前讀。

寫在最後

更多文章請訂閱公衆號"木可大大"。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章