MySQL++:默認隔離級別是什麼?

知識點傳送門:👇

1、事務管理 隔離級別


 MySQL默認隔離級別:可重複讀(Repeatable read)

來自靈魂的拷問:👇

~ 爲什麼 MySQL 選擇 "可重複讀" 作爲默認隔離級別?

正文:👇

我們先來思考一個問題,在Oracle,SqlServer中都是選擇讀已提交(Read Commited)作爲默認的隔離級別

爲什麼Mysql不選擇讀已提交(Read Commited)作爲默認隔離級別,而選擇可重複讀(Repeatable Read)作爲默認的隔離級別呢?

原因如下:👇

這個是有歷史原因的,當然要從我們的主從複製開始講起了!

主從複製,是基於什麼複製的?

  是基於binlog複製的!這裏不想去搬binlog的概念了,就簡單理解爲binlog是一個記錄數據庫更改的文件吧。

binlog有幾種格式? OK,三種,分別是

  statement:記錄的是修改SQL語句

            row:記錄的是每行實際數據的變更

         mixed:statement和row模式的混合

那Mysql在5.0這個版本以前,binlog只支持STATEMENT這種格式!

而這種格式在讀已提交(Read Commited)這個隔離級別下主從複製是有bug的,因此Mysql將可重複讀(Repeatable Read)作爲默認的隔離級別!

接下來,就要說說當binlog爲STATEMENT格式,且隔離級別爲讀已提交(Read Commited)時,有什麼bug呢?

如下圖所示,在主(master)上執行如下事務:

 此時在主(master)上執行下列語句:

select * from test;

輸出如下:

+---+
| b |
+---+
| 3 |
+---+
1 row in set

但是,你在此時在從(slave)上執行該語句,得出輸出如下:

Empty set

這樣,你就出現了主從不一致性的問題!原因其實很簡單,就是在master上執行的順序爲先刪後插!

而此時binlog爲STATEMENT格式,它記錄的順序爲先插後刪!從(slave)同步的是binglog,因此從機執行的順序和主機不一致!就會出現主從不一致!

如何解決?

  解決方案有兩種!

1):隔離級別設爲可重複讀(Repeatable Read),在該隔離級別下引入間隙鎖。當Session 1執行delete語句時,會鎖住間隙。那麼,Ssession 2執行插入語句就會阻塞住!

2):將binglog的格式修改爲row格式,此時是基於行的複製,自然就不會出現sql執行順序不一樣的問題!奈何這個格式在mysql5.1版本開始才引入。

因此由於歷史原因,mysql將默認的隔離級別設爲可重複讀(Repeatable Read),保證主從複製不出問題!


 那麼,當我們瞭解完mysql選可重複讀(Repeatable Read)作爲默認隔離級別的原因後,

接下來我們將其和讀已提交(Read Commited)進行對比;

來說明爲什麼在互聯網項目爲什麼將隔離級別設爲讀已提交(Read Commited)!

  對比 ok,我們先明白一點!項目中是不用讀未提交(Read UnCommitted)和串行化(Serializable)兩個隔離級別;

原因有二 :

  採用讀未提交(Read UnCommitted),一個事務讀到另一個事務未提交讀數據,這個不用多說吧,從邏輯上都說不過去!

  採用串行化(Serializable),每個次讀操作都會加鎖,快照讀失效,一般是使用mysql自帶分佈式事務功能時才使用該隔離級別!

(筆者從未用過mysql自帶的這個功能,因爲這是XA事務,是強一致性事務,性能不佳!互聯網的分佈式方案,多采用最終一致性的事務解決方案!)


 

 

 

 


 

 人生無常大腸包小腸

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