事務是對一組操作原子性的保障,但正是由於事務,就會出現事務a和事務b資料之間的可見性問題(髒讀,幻讀,不可重複讀)為了解決問題,才設定了隔離級別這種東西 。
隔離級別的一種實現思想就是mvcc,一行資料由於多個事務的修改可能會有多個版本。
每次讀取的是資料最新版本。
事務之間不是併發執行的。
事務在每次執行語句時會建立新的快照,關閉之前的快照。
事務開始執行,準確的說是事務第一次select時會建立快照,後續的讀操作都是從快照裡去讀資料。
是對資料庫的臨時拷貝,有個經常聽到的說法是,可重複讀是在事務開始時候的產生乙個快照,但這個快照是什麼意思,如果事務開始時,資料庫是100g,那麼我產生的快照也要100g嗎,但顯然不是的。
一行資料多個版本,如果每個事務知道自己要訪問的版本,想象乙個物件,每次事務建立乙個物件,然後事務需要判斷行資料的可見性時,呼叫這個物件就能知道結果,那我們就可以認為它是乙個快照。
我們知道,一行資料在資料庫中會有多個版本,每個版本其實都記錄了乙個事務id(row trx_id),row trx_id和read-view就能實現乙個快照的功能。
是 innodb 在實現 mvcc 時用到的一致性讀檢視,即 consistent read view,用於支援 rc(read committed,讀提交)和 rr(repeatable read,可重複讀)隔離級別的實現。
為每個事務構造了乙個陣列,用來儲存這個事務啟動瞬間,當前正在「活躍」的所有事務 id。
「活躍」指的就是,啟動了但還沒提交。陣列裡面事務 id 的最小值記為低水位,當前系統裡面已經建立過的事務 id 的最大值加 1 記為高水位。
這個檢視陣列和高水位,就組成了當前事務的一致性檢視(read-view)
這樣,對於當前事務的啟動瞬間來說,乙個資料版本的 row trx_id,有以下幾種可能:
如果落在綠色部分,表示這個版本是已提交的事務或者是當前事務自己生成的,這個資料是可見的;
如果落在紅色部分,表示這個版本是由將來啟動的事務生成的,是肯定不可見的;
如果落在黃色部分,那就包括兩種情況
a. 若 row trx_id 在陣列中,表示這個版本是由還沒提交的事務生成的,不可見;
b. 若 row trx_id 不在陣列中,表示這個版本是已經提交了的事務生成的,可見。
參考文獻:
事務到底是隔離的還是不隔離的?
Mysql 事務隔離性
事務併發所引起的跟讀取資料有關的問題,各用一句話來描述一下 1.髒讀 事務 a 讀取了事務 b 未提交的資料,並在這個基礎上又做了其他操作。讀取未提交 2.不可重複讀 事務 a 讀取了事務 b 已提交的更改資料。讀取新提交update 3.幻讀 事務 a 受到事務 b 已提交的新增資料影響。看不到已...
MySQL事務的隔離性
事務的特徵 acid 隔離級別 設定事務隔離級別 隔離級別的作用範圍 檢視事務隔離級別 事務的操作 隔離級別 髒讀不可重複讀 幻讀讀未提交 read uncommitted 可能可能 可能讀已提交 read committed 不可能可能 可能可重複讀 repeatable read 不可能不可能 ...
理解事務的隔離性
理解事務的隔離性 事務是以可控的方式對資料資源進行訪問的一組操作。其屬性包括原子性 一致性 隔離性和永續性,也就是常說的acid。其中,隔離性是針對資料資源的併發訪問,規定了各個事務之間相互影響的程度。個人認為這是事務的4個特性裡面,比較難理解的乙個。事實上,事務的隔離性可以分為4種型別的隔離級別 ...