1. 程式人生 > >Mysql 隔離級別和鎖(一)

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 隔離級別和鎖(二)