隔離級別
未提交讀(read uncommitted)
事務中的修改,即使沒有提及,對其他事務也是可見的。
提交讀(read committed)
乙個事務只能讀取已經提及的事務所做的修改。
可重複讀(repeatable read)
保證在同乙個事務中多次讀取同樣資料的結果是一樣的。
可序列化(seriakizable)
強制事務序列執行
隔離級別
髒讀不可重複讀
幻影讀未提交讀會會
會提交讀不會會
會可重複讀
不會不會
會可序列化
不會不會
不會多版本併發控制是mysql的innodb儲存引擎實現隔離級別的一種具體方式,用於實現提交讀和可重複讀這兩種隔離級別。而未提交讀隔離級別總是讀取最新的資料行,無需使用mvcc.可序列化需要對所有讀取的行加鎖,單純使用mvcc無法實現
版本號
隱藏的列
mvcc在每行記錄後面都儲存著兩個隱藏的列,用來儲存兩個版本號:
建立版本號:指示建立乙個資料行的快照時的系統版本號
刪除版本號:如果該快照的刪除版本號大於當前事務版本號表示該快照有效,否則表示該快照已經被刪除
實現過程
一下實現過程針對可重複讀隔離級別
當乙個事務開始時,該事務的版本號肯定大於當前資料行快照的建立版本號。資料行快照的建立版本號是建立資料行快照時的系統版本號,系統版本號隨著建立事務而遞增,因此新建立乙個事務時,這個事務的系統版本號比之前的系統版本號都大,也就是比所有資料行快照的建立版本號都大。
select
多個事務必須讀取同乙個資料行的快照,並且這個快照是距離現在最近的乙個有效快照。但是也有例外,如果有乙個事務正在修改該資料行,那麼它可以讀取事務本身所做的修改,而不用和其它事務的讀取結果一致
把沒有對乙個資料行做修改的事務稱為t,t所要讀取的資料行快照的建立版本號必須小於t的版本號,因此如果大於或者等於t的版本號,那麼表示該資料行快照是其它事務的最新修改,因此不能去讀取它。除此之外,t所要讀取的資料行快照的刪除版本號必須大於t的版本號,因為如果小於等於t的版本號,那麼表示該資料行快照已經被刪除,不應該去讀取
insert
當前系統版本號作為資料行快照的建立版本號
delete
當前系統版本號作為資料行快照的刪除版本號
update
將當前系統版本號作為更新前資料行快照的刪除版本號,並將當前系統版本號作為更新後的資料行快照的建立版本號,可以理解為先執行delete後執行insert
快照讀與當前讀
快照讀使用mvcc讀取的是快照中的資料,這樣可以減少加鎖鎖帶來的開銷
select
*from
table..
..;
當前讀
讀取的是最新資料,需要加鎖。一下第乙個語句需要加s鎖,其它需要加x鎖。
select
*from
table
where ? lock
inshare
mode
;select
*from
table
where ? for
update
;insert
;update
;
next-key locks是mysql的innodb儲存引擎的一種鎖實現
mvcc不能解決幻影讀問題,next-key locks就是為了解決這個問題而存在的,在可重複讀隔離級別下,使用mvcc+next-key locks可以解決幻讀問題。
record locks
鎖定乙個記錄上的索引,而不是記錄本身。
如果表沒有設定索引,innodb會自動在主鍵上建立隱藏的聚簇索引,因此record locks依然可以使用
gap locks
鎖定索引之間的間隙,但是不包含索引本身
next-key locks
它是record和gap locks的結合,不僅鎖定乙個記錄上的索引,也鎖定索引之間的間隙。
MySQL隔離級別和封鎖協議
一直以來對資料庫的事務隔離機制的理解總是停留在表面,其內容也是看一遍忘一邊。這兩天決定從原理上理解它,整理成自己的知識。查閱資料的過程中發現好多零碎的概念如果串起來足夠寫一本書,所以在這裡給自己梳理乙個脈絡,具體的內容參考引文或在網上搜一下。由於平時接觸最多的是mysql,所以文章中某些部分是mys...
MySQL事務隔離級別和MVCC
原文 mysql事務隔離級別和mvcc mvcc文章勘誤 髒讀 在乙個事務處理過程裡讀取了另乙個未提交的事務中的資料。不可重複讀 乙個事務讀取到了其他事務已經提交的資料,導致前後兩次讀取資料不一致的情況,稱為不可重複讀。幻讀 乙個事務前後兩次讀取資料不一致,是由於其他資料插入資料造成的,這種情況叫做...
Mysql 事務特性和隔離級別
事務的特性乙個事務 transaction 中的所有操作,要麼全部完成,要麼全部不完成,不會結束在中間某個環節。事務在執行過程中發生錯誤,會被回滾 rollback 到事務開始前的狀態,就像這個事務從來沒有執行過一樣。在事務開始之前和事務結束以後,資料庫的完整性沒有被破壞。這表示寫入的資料必須完全符...