Mysql事務(wù)的隔離級別(臟讀+幻讀+可重復(fù)讀)
前言:
因為InnoDB是支持事務(wù)的,所以只對InnoDB的事務(wù)進行討論。
一、事務(wù)
(一)什么是事務(wù)
事務(wù)是由一組SQL語句組成的邏輯處理單元,是一組不可分割的操作序列。
(二)事務(wù)的特征
- 原子性(Actomicity):事務(wù)是一個原子操作單元,其對數(shù)據(jù)的修改,要么全都執(zhí)行,要么全都不執(zhí)行
- 一致性(Consistent):在事務(wù)開始和完成時,數(shù)據(jù)都必須保持一致狀態(tài)。
- 隔離性(Isolation):數(shù)據(jù)庫系統(tǒng)提供一定的隔離機制,保證事務(wù)在不受外部并發(fā)操作影響的“獨立”環(huán)境執(zhí)行。
- 持久性(Durable):事務(wù)完成之后,它對于數(shù)據(jù)的修改是永久性的,即使出現(xiàn)系統(tǒng)故障也能夠保持。
(三)手動開啟、提交、回滾事務(wù)
-- 開啟事務(wù) start transaction; update user_count set balance = balance + 20 where id = 1; update user_count set balance = balance - 20 where id =2; -- 回滾事務(wù) rollback; -- 提交事務(wù) commit;
注意:在回滾和提交之前,數(shù)據(jù)庫中的數(shù)據(jù)都是操作的緩存中的數(shù)據(jù),而不是數(shù)據(jù)庫中的真實數(shù)據(jù)。
二、臟讀、幻讀、可重復(fù)讀
(一)臟讀 read uncommit
讀取到了未提交的數(shù)據(jù)。
臟讀對應(yīng)的是read uncommitted讀未提交的事務(wù)隔離級別,即從緩存中讀取數(shù)據(jù),而不是讀取已經(jīng)持久化的數(shù)據(jù)。
事務(wù)B在select的時候,讀取到了被事務(wù)A更新在緩存的數(shù)據(jù),但是該數(shù)據(jù)沒有真正的持久化到數(shù)據(jù)庫中,一旦事務(wù)A會滾,事務(wù)B就會讀到錯誤的臟數(shù)據(jù)。
(二)不可重復(fù)讀 unrepeatable
一個事務(wù)在讀取某些數(shù)據(jù)已經(jīng)發(fā)生了改變、或某些記錄已經(jīng)被刪除了!這種現(xiàn)象叫做“不可重復(fù)讀”。
不可重復(fù)讀產(chǎn)生的場景對應(yīng)的是read committed讀已提交的事務(wù)隔離級別,即事務(wù)讀取的數(shù)據(jù)都是已經(jīng)完成持久化的數(shù)據(jù)。
(三)幻讀
同一事務(wù)內(nèi),同樣的篩選條件,查詢出來的數(shù)據(jù)條數(shù)發(fā)生了變化,(另一個事務(wù)搶到CPU進行了刪除或者插入條件),這種現(xiàn)象就稱為“幻讀” 。
幻讀產(chǎn)生的場景對應(yīng)的是repeatable read可重復(fù)讀的事務(wù)隔離級別,事務(wù)讀取的數(shù)據(jù)都是已經(jīng)完成持久化的數(shù)據(jù),并且為事務(wù)在修改的數(shù)據(jù)增加行鎖,但是沒有表鎖。
(四)不可重復(fù)讀和幻讀的區(qū)別
不可重復(fù)讀針對的是同一條數(shù)據(jù),讀的是別的事務(wù)修改之前的樣子,一旦事務(wù)的隔離級別使用了unrepeatable read,加上行鎖,就可以避免產(chǎn)生。
幻讀針對的是滿足篩選條件的一批數(shù)據(jù),因為行鎖不能阻止插入和刪除數(shù)據(jù),所以會導(dǎo)致查詢到的條數(shù)是錯誤的,使用serializable可以避免。
三、事務(wù)的隔離級別
臟讀 | 不可重復(fù)讀 | 幻讀 | |
---|---|---|---|
read uncommitted | √ | √ | √ |
read committed | √ | √ | |
repeatable read | √ | ||
serializable |
設(shè)置表的隔離級別sql語言如下:
-- 查詢數(shù)據(jù)庫當(dāng)前的隔離級別 select @@transaction_isolation -- 讀未提交 set session transaction isolation level read uncommitted; -- 讀已提交 set session transaction isolation level read committed; -- 不可重復(fù)讀 set session transaction isolation level repeatable read; -- 序列化(串行執(zhí)行) set session transaction isolation level serializable;
(一)讀未提交read uncommitted
讀緩存里面的數(shù)據(jù),風(fēng)險最高但是允許的并發(fā)最多
(二)讀已提交read committed
讀持久化的數(shù)據(jù),不讀緩存的數(shù)據(jù),不加鎖
(三)不可重復(fù)讀 read repeatable
讀可持久化的數(shù)據(jù)的數(shù)據(jù),并且添加行級鎖(一個事務(wù)在修改某行數(shù)據(jù)的時候,別的事務(wù)阻塞等待提交才能讀到)
(四)序列化 serializable
最安全但是并發(fā)效率最低,讀持久化數(shù)據(jù),并且加表鎖,如果事務(wù)并發(fā)的多,需要一直阻塞,不建議使用。
事務(wù)的隔離級別從低到高依次是 read uncommitted , read committed, repeatable read , serializable 。隔離級別越低,越能支持高并發(fā)的數(shù)據(jù)操作,與此同時,也會帶來越高的并發(fā)風(fēng)險,Mysql數(shù)據(jù)庫默認的隔離級別是repeatable read 。
到此這篇關(guān)于Mysql事務(wù)的隔離級別(臟讀+幻讀+可重復(fù)讀)的文章就介紹到這了,更多相關(guān)Mysql事務(wù)隔離內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
centos7環(huán)境下二進制安裝包安裝 mysql5.6的方法詳解
這篇文章主要介紹了centos7環(huán)境下二進制安裝包安裝 mysql5.6的方法,詳細分析了centos7環(huán)境下使用二進制安裝包安裝 mysql5.6的具體步驟、相關(guān)命令、配置方法及操作注意事項,需要的朋友可以參考下2020-02-02ubuntu 16.04下mysql5.7.17開放遠程3306端口
這篇文章主要介紹了ubuntu 16.04下mysql5.7.17開放遠程3306端口的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-01-01關(guān)于mysql create routine 權(quán)限的一些說明
下面小編就為大家?guī)硪黄P(guān)于mysql create routine 權(quán)限的一些說明。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-03-03mysql 設(shè)置自動創(chuàng)建時間及修改時間的方法示例
這篇文章主要介紹了mysql 設(shè)置自動創(chuàng)建時間及修改時間的方法,結(jié)合實例形式分析了mysql針對創(chuàng)建時間及修改時間相關(guān)操作技巧,需要的朋友可以參考下2019-09-09