再有人問你MySql 的隔離級(jí)別是什么,就把這篇文章發(fā)給他!


事務(wù)是程序中一系列嚴(yán)密的操作,所有的操作必須完成,否則在所有的操作中所做的所有的更改都會(huì)被撤銷。也就是事務(wù)的原子性,一個(gè)事務(wù)中的一系列的操作要么全部成功,要么就是失敗。
事務(wù)的結(jié)束有兩種,當(dāng)事務(wù)中所有的步驟全部成功執(zhí)行的時(shí)候,事務(wù)提交。如果其中一個(gè)步驟失敗,將會(huì)發(fā)生回滾操作,撤銷到事務(wù)開始之前的所有的操作。
事務(wù)具有四個(gè)特征
原子性 事務(wù)是數(shù)據(jù)庫的邏輯工作單位,事務(wù)中包含多個(gè)操作,要么都做完,要么都不做 隔離性(隔離性也是本文的重點(diǎn)) 事務(wù)彼此之間是不能互相干擾的,即一個(gè)事務(wù)的操作對(duì)該數(shù)據(jù)庫的其他事務(wù)操作是隔離的,并發(fā)執(zhí)行的各個(gè)事務(wù)時(shí)間互補(bǔ)干擾 持久性 事務(wù)一旦提交,其變更是永久性的 一致性 事務(wù)執(zhí)行的結(jié)果必須滿足從一個(gè)狀態(tài)變到另一個(gè)狀態(tài),因此當(dāng)數(shù)據(jù)庫只包含成功事務(wù)提交的結(jié)果時(shí),就說數(shù)據(jù)庫處于一致性的狀態(tài)。如果數(shù)據(jù)庫系統(tǒng)在運(yùn)行時(shí)發(fā)生系統(tǒng)故障,有些未完成的事務(wù)被迫中止,而有一部分修改已經(jīng)寫入數(shù)據(jù)庫,這個(gè)時(shí)候數(shù)據(jù)庫就處于一種不正確的狀態(tài)。
讀取未提交的數(shù)據(jù)【Read Uncommitted】 在該隔離級(jí)別,所有的事務(wù)都可以看到其他事務(wù)沒有提交的執(zhí)行結(jié)果。(實(shí)際生產(chǎn)中不可能使用這種隔離級(jí)別的) 讀取提交的內(nèi)容【Read Committed】 該隔離級(jí)別是大多數(shù)數(shù)據(jù)庫的默認(rèn)的隔離級(jí)別(不是 MySQL 默認(rèn)的)。它滿足了隔離的簡(jiǎn)單定義:一個(gè)事務(wù)只能看到其他的已經(jīng)提交的事務(wù)所做的改變。這種隔離級(jí)別也支持不可重復(fù)讀,即同一個(gè) select 可能得到不同的結(jié)果 可重讀【Repeatable Read】 這是 MySQL 默認(rèn)的隔離級(jí)別,它確保同一個(gè)事務(wù)在并發(fā)讀取數(shù)據(jù)時(shí),會(huì)看到同樣的數(shù)據(jù)行。不過理論上會(huì)導(dǎo)致另外一個(gè)問題,【幻讀】。幻讀:相同的條件查詢一些數(shù)據(jù),然后其他事務(wù)【新增】或者是【刪除】了該條件的數(shù)據(jù),然后導(dǎo)致讀取的結(jié)果不一樣多。InnoDB 存儲(chǔ)引擎通過多版本控制(MVCC)機(jī)制解決了該問題 可串行化【serializable】 這是事務(wù)的最高隔離級(jí)別,它通過強(qiáng)制事務(wù)排序,使之不可能相互沖突,從而解決了幻讀的問題。它在每個(gè)讀的數(shù)據(jù)行上面加上共享鎖,。但是可能會(huì)導(dǎo)致超時(shí)和鎖競(jìng)爭(zhēng)(這種隔離級(jí)別太極端,實(shí)際生產(chǎn)基本不使用)
臟讀 讀取了前一個(gè)事務(wù)未提交的或者是回滾的數(shù)據(jù) 不可重復(fù)度 同樣的 select 查詢,但是結(jié)果不同,過程中有事務(wù)更新了原有的數(shù)據(jù) 幻讀 兩次查詢的結(jié)果數(shù)量不一樣,過程中有事務(wù)新增或者是刪除數(shù)據(jù)

show variables like '%isolation%'
set session transaction isolation level Read Uncommitted;
Read Uncommitted實(shí)驗(yàn)一:Read Uncommitted
Read Uncommitted 即:讀取未提交set session transaction isolation level Read Uncommitted;


start tracsaction;
select * from test;
start transaction;
select * from test;
update test set num =10 where id = 1;B沒有提交事務(wù)

rollback;
select * from test;
select * from test;
實(shí)驗(yàn)二:讀取已提交-Read Committed
Read Committed;set session transaction isolaction level Read Committed;


start transaction;
select *from test;
start transaction;
select * from test;
update test set num =10 where id=1
select * from test;
commit;
select * from test;
Read Committed 讀已提交的隔離級(jí)別解決了臟讀的問題,但是出現(xiàn)了不可重復(fù)讀的問題,即事務(wù)A在兩次查詢的結(jié)果不一致,因?yàn)樵趦纱尾樵冎g事務(wù)B更新了一條數(shù)據(jù)。實(shí)驗(yàn)三:可重讀度-Repeatable Read
set session transaction isolation level repeatable read;
start transaction;
select * from test;
start transaction;
select * from test;
update test set num=10 where id=1;
select * from test;

commit;
select * from test;此時(shí)A查詢的記錄仍然和之前一樣
inset into test(num) value(4);
select * from test;

Repeatable Read隔離級(jí)別只允許讀取已經(jīng)提交的事務(wù)的記錄,實(shí)驗(yàn)四:串行化-Serializable





serializable完全鎖定字段,若一個(gè)事務(wù)來操作同一份數(shù)據(jù),那么就必須等待,直到前一個(gè)事務(wù)完成并解除鎖為止。是完整的隔離級(jí)別,會(huì)鎖住對(duì)應(yīng)的數(shù)據(jù)表,因?yàn)闀?huì)導(dǎo)致效率問題。往期推薦

密碼打馬賽克已經(jīng)不安全了!這款開源的去“馬賽克“工具一秒還原

身家破億!86版西游記“紅孩兒”拒絕出道成學(xué)霸,已是中科院博士,名下52家公司

帶爸媽去上海東方明珠旋轉(zhuǎn)餐廳體驗(yàn)了一把
直面Java第360期:如何使用樂觀鎖提升高并發(fā)的吞吐率并且不會(huì)超賣
深入并發(fā)第015期:多線程代碼如何Debug?
評(píng)論
圖片
表情
