在MySQL中,實現了這四種隔離級別,分別有可能產生問題以下所示:數據庫
首先建立一個表account。建立表的過程略過(因爲InnoDB存儲引擎支持事務,因此將表的存儲引擎設置爲InnoDB)。表的結構以下:session
表結構性能
而後往表中插入兩條數據,插入後結果以下:spa
數據code
爲了說明問題,咱們打開兩個控制檯分別進行登陸來模擬兩個用戶(暫且成爲用戶A和用戶B吧),並設置當前MySQL會話的事務隔離級別。blog
具體用戶A的操做以下:事務
set session transaction isolation level read uncommitted; start transaction; select * from account;
結果以下:it
數據io
用戶B的操做以下:table
set session transaction isolation level read uncommitted; start transaction; update account set account=account+200 where id = 1;
隨後咱們在A用戶中查詢數據,結果以下:
uncommittedA數據
那就是咱們在一個事務中能夠隨隨便便讀取到其餘事務未提交的數據,這仍是比較麻煩的,咱們叫髒讀。我不知道這個名字是怎麼起的,爲了加強你們的印象,能夠這麼想,這個事務好輕浮啊,飢渴到連別人沒提交的東西都等不及,真髒,呸!
實際上咱們的數據改變了嗎?
答案是否認的,由於只有事務commit後纔會更新到數據庫。
一樣的辦法,咱們將用戶B所在的會話當前事務隔離級別設置爲read commited。
在用戶A所在的會話中咱們執行下面操做:
update account set account=account-200 where id=1;
read committed
咱們將id=1的用戶account減200。而後查詢,發現id=1的用戶account變爲800。
在B用戶所在的會話中查詢:
select * from account;
結果以下:
read committedB
咱們會發現數據並無變,仍是1000。
接着在會話A中咱們將事務提交:
commit;
在會話B中查詢結果以下:
read committedB1
那就是咱們在會話B同一個事務中,讀取到兩次不一樣的結果。這就形成了不可重複讀,就是兩次讀取的結果不一樣。這種現象叫不可重複讀。
如今有個需求,就是老闆說在同一個事務中查詢結果必須保持一致,若是你是數據庫,你會怎麼作?數據庫是這麼作的。
在會話B中咱們當前事務隔離級別爲repeatable read。具體操做以下:
set session transaction isolation level repeatable read; start transaction;
接着在會話B中查詢數據:
repeatablereadB1
咱們在A用戶所在會話中爲表account添加一條數據:
insert into account(id,account) value(3,1000); commit;
而後咱們查詢看數據插入是否成功:
repeatable readA
回到B用戶所在的會話,咱們查詢結果:
repeatablereadB2
用戶B在他所在的會話中想插入一條新數據id=3,value=1000。來咱們操做下:
readpeatablereadB3
用戶B固然不服啊,由於查詢到數據只有兩條啊,爲何插入id=3說我數據重複了呢?
我再看一遍,莫非我眼花了?
repeatablereadB2
試想一下,在實際中用戶A和用戶B確定是相互隔離的,彼此不知道操做什麼。用戶B碰到這種現象,確定會炸毛的啊,明明不存在的數據,插入卻說主鍵id=3數據重複了。
管他呢,老闆的要求知足了。要一個事務中讀取的數據一致(可重複讀)。我只能這麼作啊,打腫臉裝胖子。數據已經發生改變,可是我仍是要保持一致。可是,出現了用戶B面對的問題,這種現象叫幻讀(記得當時就在這個地方糾結很久,到底什麼是幻讀啊)。
一樣,咱們將用戶B所在的會話的事務隔離級別設置爲serializable並開啓事務。
set session transaction isolation level serializable; start transaction;
在用戶B所在的會話中咱們執行下面操做:
select * from account;
結果以下:
serializableA
那咱們這個時候在用戶A所在的會話中寫數據呢?
readcommittedA1
咱們發現用戶A所在的會話陷入等待,若是超時(這個時間能夠進行配置),會出現Lock wait time out提示:
readcommittedA2
若是在等待期間咱們用戶B所在的會話事務提交,那麼用戶A所在的事務的寫操做將提示操做成功。