Mysql 隔離級別和鎖(一)
成功不是將來才有的,而是從決定去做的那一刻起,持續累積而成。
1、事務的4大特徵ACID
Atomicity Consistency Isolation Durability(原子、一致、隔離、持久)
說明 | 隔離級別 | 髒讀 | 不可重複讀 | 幻讀 | 加鎖 |
---|---|---|---|---|---|
未提交讀 | READ UNCOMMITTED | YES | YES | YEs | NO |
提交讀 | READ COMMITTED | NO | YES | YEs | NO |
重複讀 | REPEATABLE READ | NO | NO | YEs | NO |
序列讀 | SERIALIZABLE | NO | NO | NO | YEs |
2、四種隔離級別分別會產生的問題
ANSI/ISO SQL標準定義了4中事務隔離級別:未提交讀(read uncommitted),提交讀(read committed),重複讀(repeatable read),序列讀(serializable)。
對於不同的事務,採用不同的隔離級別分別有不同的結果。不同的隔離級別有不同的現象。主要有下面3種現象:
髒讀(Drity Read)
某個事務已更新一份資料,另一個事務在此時讀取了同一份資料,由於某些原因,前一個RollBack了操作,則後一個事務所讀取的資料就會是不正確的。
示例:我們可以通過例項來具體的看一下什麼叫做髒讀,首先我們需要建立一個測試表 test
然後開啟雙視窗模擬迸發操作~
常用的命令:
查詢事務的隔離級別,分別是:全域性的、下次事務的、當前事務的隔離級別
show variables like '%storage_engine%'; 檢視當前的mysql引擎 show variables like 'autocommit'\G; 檢視是否自動提交 select @@global.tx_isolation,@@tx_isolation,@@session.tx_isolation; set session transaction isolation level READ UNCOMMITTED; 修改當前事務隔離級別
①、兩個操作視窗同時開啟事務,然後在右側視窗更新其中的一條記錄,左側去查,我們看一下結果如何?
在此之前我們分別查一下當前事務的隔離級別是什麼?
查詢結果顯示:
當前mysql的隔離級別是:**REPEATABLE-READ** 重複讀,這種隔離級別也是大多數mysql的預設的隔離級別,現在我們先測試未提交讀(**read uncommitted**),那麼我們首先需要將資料庫的隔離級別修改一下
方法如下:
set session transaction isolation level READ UNCOMMITTED;
我們在左邊的事務中修改某一條記錄,然後在右邊的事務中我們去查詢這條記錄看一下會是什麼樣的結果?
右邊事務中我們獲取到的值為id=4的name=14,然後我們去回滾左邊事務。
注意:在測試的過程中發現了一個bug,那就是我的事務居然沒有生效?這是什麼原因呢?
答案:在mysql命令列的預設下,事務都是自動提交的,sql語句提交後馬上會執行commit操作。因此開啟一個事務必須使用begin,start transaction,或者執行 set autocommit=0;
才可以使用的事務控制語句。這塊新手可能會遇到這個問題,需要注意一下。(還會有一種問題就是:一定要注意你所操作的當前表的儲存引擎是什麼?MYISAM不支援事務的,所以需要將表修改為innoDB,檢視看方法:show create table test1; 修改方法:alter table test1 engin=innodb(老鳥一般都知道,只是建議小鳥們))
左邊事務更新一條欄位以後,查詢表顯示資料已經更新成功,右邊事務查詢表資料同樣顯示結果與左側事務相同,然後我們回滾左邊事務,再次查詢發現數據還原了,右邊事務查詢結果顯示資料跟上一次查詢不一致,這就導致了右邊事務之前所查詢得到的資料是錯誤的資料,所以對於右邊事務來說就造成了“髒讀”。
後面演示請繼續參考 Mysql 隔離級別和鎖(二)