MySQL 事務管理

一、前言

CURD 不加控制,會有什么問題?

CURD 滿足什么屬性,能解決上述問題?

  1. 買票的過程得是原子的。
  2. 買票應該不能受互相的影響。
  3. 買完票應該要永久有效。
  4. 買前和買后都要是確定的狀態。

什么是事務?

  • 事務就是一組 DML 語句組成,這些語句在邏輯上存在相關性,這一組 DML 語句要么全部成功,要么全部失敗,是一個整體。MySQL 提供一種機制,保證我們達到這樣的效果。事務還規定不同的客戶端看到的數據是不相同的。
  • 事務就是要做的或所做的事情,主要用于處理操作量大、復雜度高的數據。假設一種場景:你畢業了,學校的教務系統后臺 MySQL 中,不再需要你的數據,要刪除你的所有有關信息(一般不會),那么要刪除你的基本信息(姓名、電話、籍貫等)的同時,也刪除和你有關的其他信息,比如:你的各科成績,你的在校表現,甚至你在論壇發過的帖子、文章等。這樣就需要多條 MySQL 語句構成,那么所有這些操作合起來就構成了一個事務。
  • 正如上面所說,一個 MySQL 數據庫,可不止你一個事務在運行,同一時刻甚至有大量的請求被包裝成事務,再向 MySQL 服務器發起事務處理請求。而每條事務至少一條 SQL,最多很多 SQL,這樣如果大家都訪問同樣的表數據,在不加保護的情況下就絕對會出現問題。甚至因為事務由多條 SQL 構成,那么也會存在執行到一半出錯或者不想再執行的情況,那么已經執行的怎么辦呢?

一個完整的事務,絕對不是簡單的?sql?集合,還需要滿足如下四個屬性:?

  • 原子性:一個事務(transaction)中的所有操作,要么全部完成,要么全部不完成,不會結束在中間某個環節。事務在執行過程中發生錯誤,會被回滾(Rollback)到事務開始前的狀態,就像這個事務從來沒有執行過一樣。
  • 一致性:在事務開始之前和事務結束以后,數據庫的完整性沒有被破壞。這表示寫入的資料必須完全符合所有的預設規則,這包含資料的精確度、串聯性以及后續數據庫可以自發性地完成預定的工作。
  • 隔離性:數據庫允許多個并發事務同時對其數據進行讀寫和修改的能力,隔離性可以防止多個事務并發執行時由于交叉執行而導致數據的不一致。事務隔離分為不同級別,包括讀未提交(Read uncommitted)、讀提交(read committed)、可重復讀(repeatable read)和串行化(Serializable )。
  • 持久性:事務處理結束后,對數據的修改就是永久的,即便系統故障也不會丟失。

上面四個屬性,可以簡稱為?ACID?。

  • 原子性Atomicity,或稱不可分割性)
  • 一致性Consistency)
  • 隔離性Isolation,又稱獨立性)
  • 持久性Durability)

為什么會出現事務?

事務被 MySQL 編寫者設計出來, 本質是為了當應用程序訪問數據庫時, 事務能夠簡化我們的編程模型, 不需要我們去考慮各種各樣的潛在錯誤和并發問題。 可以想一下當我們使用事務時, 要么提交, 要么回滾, 我們不會去考慮網絡異常了, 服務器宕機了, 同時更改一個數據該怎么辦。
因此事務本質上是為了應用層服務 的。 而不是伴隨著數據庫系統天生就有的。
(提示:我們后面把 MySQL 中的一行信息,稱為一行記錄。)

二、事務的版本支持

在?MySQL?中只有使用了?Innodb?數據庫引擎的數據庫或表才支持事務,?MyISAM?不支持

1、查看數據庫引擎

(1)表格顯示

?(2) 行顯示

三、事務提交方式

1、事務的提交方式

常見的事務的提交方式有兩種:

  1. 自動提交
  2. 手動提交

2、查看事務提交方式

四、事務常見操作方式

1、練習 ——?簡單銀行用戶表

(1)提前準備

  • Centos 7 云服務器,默認開啟 3306 mysqld 服務


  • 使用 Win cmd 遠程訪問 Centos 7 云服務器,mysqld 服務(需要 Win 上也安裝了 MySQL,這里看到結果即可)
  • 注意:使用本地 MySQL 客戶端可能看不到鏈接效果,本地可能使用域間套接字查不到鏈接。


  • 使用 netstat 查看鏈接情況,可知:MySQL?本質是一個客戶端進程

?


  • 為了便于演示,我們將 MySQL?的默認隔離級別設置成讀未提交。

(2)創建測試表

(3)正常演示?——?證明事務的開始與回滾

(4)非正常演示

A.?證明未?commit,客戶端崩潰,MySQL?自動會回滾(隔離級別設置為讀未提交)

  • 終端 A


  • 終端 B

B. 證明?commit?了,客戶端崩潰,MySQL?數據不會在受影響,已經持久化

  • 終端 A


  • 終端 B

C. 對比試驗。證明?begin?操作會自動更改提交方式,不會受?MySQL?是否自動提交影響

  • 終端 A

D. 證明單條?SQL?與事務的關系

a. 實驗一

  • 終端 A


  • 終端 B

b. 實驗二

  • 終端 A


  • 終端 B

?2、結論

  • 只要輸入 begin / start transaction,事務便必須要通過 commit 提交,才會持久化,與是否設置 set autocommit 無關。
  • 事務可以手動回滾,同時,當操作異常,MySQL 會自動回滾。
  • 對于 InnoDB 每一條 SQL 語言都默認封裝成事務,自動提交。(select 有特殊情況,因為 MySQL 有 MVCC )
  • 從上面的例子,我們能看到事務本身的原子性(回滾),持久性(commit)。

3、事務操作注意事項?

  • 如果沒有設置保存點,也可以回滾,但只能回滾到事務的開始。直接使用 rollback(前提是事務還沒有提交)。
  • 如果一個事務被提交了(commit),則不可以回退(rollback)。
  • 可以選擇回退到哪個保存點。
  • InnoDB 支持事務, MyISAM 不支持事務。
  • 開始事務可以用 start transaction / begin。

五、事務隔離級別?

1、如何理解隔離性

  • ?MySQL 服務可能會同時被多個客戶端進程(線程)訪問,訪問的方式以事務方式進行。
  • 一個事務可能由多條 SQL 構成,也就意味著任何一個事務都有執行前、執行中、執行后的階段。而所謂的原子性,其實就是讓用戶層要么看到執行前,要么看到執行后,執行中出現問題可以隨時回滾。所以單個事務對用戶表現出來的特性就是原子性。
  • 但畢竟所有事務都要有個執行過程,那么在多個事務各自執行多個 SQL 時,就還是有可能會出現互相影響的情況。比如:多個事務同時訪問同一張表,甚至同一行數據。
  • 假設你媽媽給你說:你要么別學,要學就學到最好。至于你怎么學,中間有什么困難,你的媽媽并不關心。那么你的學習對于你媽媽來說,就是原子的。那么你的學習過程很容易受別人干擾,此時就需要將你的學習隔離開,以保證你的學習環境是健康的。
  • 在數據庫中,為了保證事務執行過程中盡量不受干擾,就有了一個重要特征:隔離性。
  • 在數據庫中,允許事務受不同程度的干擾,就有了一種重要特征:隔離級別。

2、隔離級別?

  • 讀未提交【Read Uncommitted】在該隔離級別,所有的事務都可以看到其他事務沒有提交的執行結果。(實際生產中不可能使用這種隔離級別的)但相當于沒有任何隔離性,也會有很多并發問題,如臟讀、幻讀、不可重復讀等,我們前面為了做實驗方便,用的就是這個隔離性。
  • 讀提交【Read Committed】該隔離級別是大多數據庫的默認的隔離級別(不是 MySQL 默認的)。它滿足了隔離的簡單定義:一個事務只能看到其他的已經提交的事務所做的改變。這種隔離級別會引起不可重復讀,即一個事務執行時,如果多次 select,可能得到不同的結果。
  • 可重復讀【Repeatable Read】這是 MySQL 默認的隔離級別,它確保同一個事務在執行中,多次讀取操作數據時,會看到同樣的數據行,但是會出現幻讀問題。
  • 串行化【Serializable】這是事務的最高隔離級別,它通過強制事務排序,使之不可能相互沖突,從而解決了幻讀的問題。它在每個讀的數據行上面加上共享鎖,但可能會導致超時和鎖競爭(這種隔離級別太極端,實際生產基本不使用)。

隔離級別如何實現:隔離,基本都是通過鎖實現的,不同的隔離級別,鎖的使用是不同的。常見的有:表鎖、行鎖、讀鎖、寫鎖、間隙鎖(GAP)、Next-Key 鎖(?GAP+?行鎖)?等。不過,我們目前現有這個認識就行,先關注上層使用。

3、查看與設置隔離性

(1)查看

(2)設置

  • 設置當前會話 /?全局隔離級別

set [session?| global] transaction isolation level?{read uncommitted | read committed |?repeatable read | serializable}?;

注意:改變當前會話隔離級別,重啟不受影響。但改變全局隔離級別的話,重啟之后默認值會發生改變。


  • 設置當前會話隔離性,另起一個會話,看不多,只影響當前會話

串行化:

set session transaction isolation level serializable;

注意:如果沒有現象,關閉 M?ySQL??客戶端,重新連接。?

4、讀未提交【Read Uncommitted】?

幾乎沒有加鎖,雖然效率高,但是問題太多,嚴重不建議采用。

  • 終端 A


  • 終端 B

?一個事務在執行中,讀到另一個執行中事務的更新或其他操作,但是未?commit?的數據,這種現象叫做臟讀(dirty read)。??

?5、?讀提交【Read Committed】

  • 終端 A


  • 終端 B

終端 B 進行第 2 次 select * from account 之前,此時還在當前事務中,并未 ?commit ,那么就造成了在同一個事務內進行同樣的讀取,在不同的時間段( 依舊還在事務操作中) ,讀取到了不同的值,這種現象叫做不可重復讀( non reapeatable read)

6、可重復讀【Repeatable Read】

  • 終端 A

?


  • 終端 B

在終端 B commit 之前可以看到,?事務無論什么時候進行查找,看到的結果都是一致的,這叫做可重復讀

如果將上面的終端 A 中的 update 操作,改成 insert 操作,會有什么問題?

  • 終端 A

  • 終端 B

select * from account; ?多次查看,發現終端 ?A ?在對應事務中 ?insert ?的數據在終端 ?B ?的事務周期中,也沒有什么影響,也符合可重復的特點。但一般的數據庫在可重復讀情況的時候,無法屏蔽其他事務 insert ?的數據。

為什么?
因為隔離性實現是對數據加鎖完成的,而 insert ?待插入的數據因為并不存在,那么一般加鎖無法屏蔽這類問題, 會造成雖然大部分內容是可重復讀的,但是 insert ?的數據在可重復讀情況被讀取出來,導致多次查找時會多查找出來新的記錄,就如同產生了幻覺。這種現象,叫做幻讀(phantom read) 。

很明顯,?MySQL??在??RR??級別的時候,是解決了幻讀問題的(?解決的方式是用 Next-Key 鎖(?GAP+?行鎖)?解決的。

?7、串行化【serializable】?

對所有操作全部加鎖,進行串行化不會有問題,但是只要串行化,效率就很低,幾乎完全不會被采用。

  • 終端 A?


  • 終端 B

?

8、總結?

  • ?其中隔離級別越嚴格,安全性越高,但數據庫的并發性能也就越低,往往需要在兩者之間找一個平衡點。
  • 不可重復讀的重點是修改和刪除:同樣的條件, 你讀取過的數據,再次讀取出來發現值不一樣了 幻讀的重點在于新增:同樣的條件在第 1 次和第 2 次讀出來的記錄數不一樣。
  • 說明:MySQL 默認的隔離級別是可重復讀,一般情況下不要修改。
  • 上面的例子可以看出,事務也有長短事務這樣的概念。事務間互相影響,指的是事務在并行執行的時候,即都沒有 commit 的時候,影響會比較大。

?

六、一致性(Consistency)?

  • ?事務執行的結果,必須使數據庫從一個一致性狀態,變到另一個一致性狀態。當數據庫只包含事務成功提交的結果時,數據庫處于一致性狀態。如果系統運行發生中斷,某個事務尚未完成而被迫中斷,而改未完成的事務對數據庫所做的修改已被寫入數據庫,此時數據庫就處于一種不正確(不一致)的狀態。因此一致性是通過原子性來保證的。
  • 其實一致性和用戶的業務邏輯強相關,一般 MySQL 提供技術支持,但是一致性還是要用戶業務邏輯做支撐,也就是一致性是由用戶決定的。
  • 而技術上,通過 AID 保證 C。

七、擴展學習(了解)?

如何實現事務的隔離性-CSDN博客

Innodb 中的事務隔離級別和鎖的關系-CSDN博客

Mysql 間隙鎖原理,以及 Repeatable Read 隔離級別下可以防止幻讀原理-CSDN博客

在?RR?級別的時候,多個事務的?update,多個事務的?insert,多個事務的?delete,是否會有加鎖現象?

現象結果是,?update?,?insert?,?delete??之間是會有加鎖現象的,但是??select??和這些操作是不沖突的。這就是通過讀寫鎖(鎖有行鎖 / 表鎖)?+ MVCC??完成隔離性。?

八、如何理解隔離性(深度)?

?數據庫并發的場景有三種:

  • 讀-?:不存在任何問題,也不需要并發控制。
  • 讀-寫?:有線程安全問題,可能會造成事務隔離性問題,可能遇到臟讀、幻讀、不可重復讀。
  • 寫-?:有線程安全問題,可能會存在更新丟失問題,比如第一類更新丟失,第二類更新丟失(后面補充)。

?1、讀-寫?

多版本并發控制(?MVCC?)?是一種用來解決?讀-寫沖突?的?無鎖并發控制

為事務分配單向增長的事務 ID,為每個修改保存一個版本,版本與事務??ID??關聯,讀操作只讀該事務開始前的數據庫的快照。 所以 MVCC?可以為數據庫解決以下問題:

  • 在并發讀寫數據庫時,可以做到在讀操作時不用阻塞寫操作,寫操作也不用阻塞讀操作,提高了數據庫并發讀寫的性能。
  • 同時還可以解決臟讀、幻讀、不可重復讀等事務隔離問題,但不能解決更新丟失問題。
  • 每個事務都要有自己的事務 ID,可以根據事務 ID 的大小來決定事務到來的先后順序。
  • mysqld 可能會面臨處理多個事務的情況,事務也有自己的生命周期,mysqld 要對多個事務進行管理,先描述,再組織。事務在我看來,mysqld 中一定是對應的一個或者一套結構體對象 / 類對象,事務也要有自己的結構體。

理解?MVCC?需要知道三個前提知識:

  • 3?個記錄隱藏字段
  • undo?日志
  • Read View

(1)3?個記錄隱藏列字段?

  • ?DB_TRX_ID:6 byte,最近修改(修改 / 插入)事務 ID,記錄創建這條記錄 / 最后一次修改該記錄的事務 ID。
  • DB_ROLL_PTR:7 byte,回滾指針,指向這條記錄的上一個版本(簡單理解成指向歷史版本就行,這些數據一般在 undo log 中)。
  • DB_ROW_ID:6 byte,隱含的自增 ID(隱藏主鍵),如果數據表沒有主鍵,InnoDB 會自動以 DB_ROW_ID 產生一個聚簇索引。
  • 補充:實際還有一個刪除?flag?隱藏字段,既記錄被更新或刪除并不代表真的刪除,而是刪除?flag?變了

?

假設測試表結構是:

上面描述的意思是:

目前并不知道創建該記錄的事務??ID?,隱式主鍵,我們就默認設置 成?null?,?1?。第一條記錄也沒有其他版本,我們設置回滾指針為 null?。?

(2)undo 日志?

MySQL 將來是以服務進程的方式,在內存中運行。
之前所學的所有機制:索引、事務、隔離性、日志等都是在內存中完成的,即在 MySQL 內部的相關緩沖區中保存相關數據,完成各種判斷操作。然后在合適的時候將相關數據刷新到磁盤當中的。
所以,理解 ?undo log ? 簡單理解成就是 MySQL 中的一段 內存緩沖區 ,用來保存日志數據的就行。

(3)模擬 MVCC?

?現在有一個事務??10?,對??student??表中記錄進行修改(?update):?將??name(?張三?)??改成??name(?李四?)?。

  • 事務 10 因為要修改,所以要先給該記錄加行鎖。
  • 修改前,現將改行記錄拷貝到 undo log 中。所以,undo log 中就有了一行副本數據。(原理就是寫時拷貝)
  • 所以現在 MySQL 中有兩行同樣的記錄。現在修改原始記錄中的 name,改成 '李四',并且修改原始記錄的隱藏字段 DB_TRX_ID 為當前 事務 10 的 ID,我們默認從 10 開始,之后遞增。而原始記錄的回滾指針 DB_ROLL_PTR 列,里面寫入 undo log 中副本數據的地址,從而指向副本記錄,表示我的上一個版本就是它。
  • 事務 10 提交,釋放鎖。?

?

(此時,最新的記錄是 '?李四'???那條記錄)

現在又有一個事務??11?,對??student??表中記錄進行修改(?update)?:將??age(28)??改成??age(38)?。

  • 事務 11 因為也要修改,所以要先給該記錄加行鎖。
  • 修改前,現將改行記錄拷貝到 undo log 中。所以,undo log 中就又有了一行副本數據。此時,新的副本我們采用頭插方式,插入 undo log。
  • 現在修改原始記錄中的 age 改成 38,并且修改原始記錄的隱藏字段 DB_TRX_ID 為當前事務 11 的 ID。而原始記錄的回滾指針 DB_ROLL_PTR 列里面寫入 undo log 中副本數據的地址,從而指向副本記錄,既表示我的上一個版本就是它。
  • 事務11提交,釋放鎖。

這樣,就有了一個基于鏈表記錄的歷史版本鏈。所謂的回滾無非就是用歷史數據覆蓋當前數據。?

上面的一個個版本,我們可以稱之為一個個的?快照?。?

【思考】

上面是以更新(upadte)主講的,如果是?delete?呢?

一樣的,別忘了,刪數據不是清空,而是設置??flag??為刪除即可,也可以形成版本。

?如果是?insert?呢?

因為 ?insert ?是插入,也就是之前沒有數據,那么 ?insert ?也就沒有歷史版本。但是一般為了回滾操作,insert ?的數據也是要被放入 ?undo log ?中,如果當前事務 ?commit ?了,那么這個 ?undo log 的歷史 ?insert ?記錄就可以被清空了。

總結:也就是可以理解成??update??和??delete??可以形成版本鏈,?insert??暫時不考慮。


那么 select 呢?

select??不會對數據做任何修改,所以為??select??維護多版本沒有意義。?

此時有個問題,就是 select 讀取,是讀取最新的版本呢?還是讀取歷史版本??

  • 當前讀:讀取最新的記錄,就是當前讀。增刪改,都叫做當前讀,select?也有可能當前讀,比如:select lock in share mode(共享鎖),select for update。
  • 快照讀:讀取歷史版本(一般而言),就叫做快照讀。(這個后面重點討論)

可以看到,在多個事務同時刪改查時都是當前讀,是要加鎖的。那同時有 ?select ?過來,如果也要讀取最新版( 當前讀) ,那么也就需要加鎖,這就是串行化。
但如果是快照讀,讀取歷史版本的話,是不受加鎖限制的,也就是可以并行執行。換而言之,提高了效率,即 ?MVCC ?的意義所在。

那么是什么決定了?select?是當前讀還是快照讀呢?

隔離級別。

那為什么要有隔離級別呢?

事務都是原子的。所以無論如何,事務總有先有后。

但是經過上面的操作可以發現,事務從 ?begin->CURD->commit ?是有一個階段的,也就是事務有執行前,執行中,執行后的階段。但不管怎么啟動多個事務,總是有先有后的。
那么多個事務在執行中的 ?CURD ?操作是會交織在一起的。那為了保證事務的 ?“ 有先有后 ” ,是不是應該讓不同的事務看到它該看到的內容,這就是所謂的隔離性與隔離級別要解決的問題。

先來的事務應不應該看到后來的事務所做的修改呢? 那么如何保證不同的事務看到不同的內容呢?也就是如何實現隔離級別?

(4)Read View?

?Read View ? 就是事務進行 快照讀 操作的時候生產的 讀視圖 ( Read View) ,在該事務執行的快照讀的那一刻會生成數據庫系統當前的一個快照,記錄并維護系統當前活躍事務的 ID( 當每個事務開啟時都會被分配一個 ?ID, 這個 ?ID ?是遞增的,所以最新的事務 ID ?值越大)

Read View 在 MySQL 源碼中 就是一個 類 ,本質是用來進行可見性判斷的。 即當我們某個事務執行快照讀的時候,對該記錄創建一個 Read View 讀視圖,把它比作條件 用來判斷當前事務能夠看到哪個版本的數據,既可能是當前最新的數據,也有可能是該行記錄的 undo log 里面的某個版本的數據。?

下面是簡化過的?ReadView?結構:?

class ReadView {// ...private:// 高水位,大于等于這個ID的事務均不可見trx_id_t m_low_limit_id// 低水位:小于這個ID的事務均可見trx_id_t m_up_limit_id;// 創建該 Read View 的事務IDtrx_id_t m_creator_trx_id;// 創建視圖時的活躍事務id列表ids_t m_ids;// 配合purge,標識該視圖不需要小于m_low_limit_no的UNDO LOG// 如果其他視圖也不需要,則可以刪除小于m_low_limit_no的UNDO LOGtrx_id_t m_low_limit_no;// 標記視圖是否被關閉bool m_closed;// ...
};
m_ids;          // 一張列表,用來維護Read View生成時刻,系統正活躍的事務IDup_limit_id;    // 記錄m_ids列表中事務ID最小的IDlow_limit_id;   // ReadView生成時刻系統尚未分配的下一個事務ID,也就是目前已出現過的事務ID的最大值+1creator_trx_id; // 創建該ReadView的事務ID

我們在實際讀取數據版本鏈的時候,是能讀取到每一個版本對應的事務 ?ID ?的,即當前記錄的 ?DB_TRX_ID 。
那我們現在手里面有的東西就有,當前快照讀的 ReadView 和 版本鏈中的某一個記錄的 DB_TRX_ID 。
所以現在的問題就是,當前快照讀應不應該讀到當前版本記錄。(下圖可解決該問題)

?

Read View 是事務可見性的一個類,不識事務創建出來就有的,而是當這個事務(已經存在)首次進行快照讀時,MySQL 形成的。?

對應源碼策略:???

如果查到不應該看到當前版本,接下來就是遍歷下一個版本,直到符合條件就可以看到。上面的??readview?是當你進行 select??時會自動形成。

(5)整體流程

  • 假設當前有條記錄:

  • ?事務操作:

事務??4?:修改??name(?張三?)?變成??name(?李四?)。

當?事務??2?對某行數據執行了?快照讀?,數據庫為該行數據生成一個?Read View?讀視圖。

// 事務2的 Read View
m_ids;          // 1, 3
up_limit_id;    // 1
low_limit_id;   // 4+1=5,原因:ReadView生成時刻,系統尚未分配的下一個事務ID
creator_trx_id; // 2
  • 此時版本鏈是:??

  • 只有事務??4??修改過該行記錄,并在事務??2??執行快照讀前,就提交了事務。

  • 事務?2?在快照讀該行記錄時會拿該行記錄的?DB_TRX_ID?去跟?up_limit_id,low_limit_id?和活

    躍事務??ID??列表?(trx_list)?進行比較,判斷當前事務??2??能看到該記錄的版本。

// 事務2的 Read View
m_ids;          // 1, 3
up_limit_id;    // 1
low_limit_id;   // 4+1=5,原因:ReadView生成時刻,系統尚未分配的下一個事務ID
creator_trx_id; // 2// 事務4提交的記錄對應的事務ID
DB_TRX_ID=4// 比較步驟
DB_TRX_ID(4)< up_limit_id(1) ? 不小于,下一步
DB_TRX_ID(4)>= low_limit_id(5) ? 不大于,下一步
m_ids.contains(DB_TRX_ID) ? 不包含,說明,事務4不在當前的活躍事務中。// 結論
事務4的更改應該看到。
所以事務2能讀到的最新數據記錄是事務4所提交的版本,而事務4提交的版本也是全局角度上最新的版本

(6)RR 與?RC?的本質區別

a. 當前讀和快照讀在?RR?級別下的區別

select * from user lock in share mode?以加共享鎖方式進行讀取,對應的就是當前讀。

  • 測試用例1 -?表1:?

  • 測試用例2 -?表2:
  • 用例?1?與用例?2?唯一區別僅僅是表?1?的事務?B?在事務?A?修改?age?前快照讀過一次?age?數據。
  • 而表?2?的事務?B?在事務?A?修改?age?前沒有進行過快照讀。

【結論】

  • 事務中快照讀的結果是非常依賴該事務首次出現快照讀的地方,即某個事務中首次出現快照讀,決定該事務后續快照讀結果的能力?delete 也同樣如此

【總結 ——?RR??RC?的本質區別?

  • ?正是 Read View 生成時機的不同,從而造成 RC 和 RR 級別下快照讀的結果的不同。
  • 在 RR 級別下的某個事務的對某條記錄的第一次快照讀會創建一個快照及 Read View 將當前系統活躍的其他事務記錄起來。
  • 此后在調用快照讀時,使用的還是同一個 ?Read View,所以只要當前事務在其他事務提交更新之前使用過快照讀,那么之后的快照讀使用的都是同一個 Read View,所以對之后的修改不可見。
  • 即 RR 級別下,快照讀生成 Read View 時,Read View 會記錄此時所有其他活動事務的快照,這些事務的修改對于當前事務都是不可見的。而早于 Read View 創建的事務所做的修改均是可見的。
  • 而在 RC 級別下的,事務中,每次快照讀都會新生成一個快照和 Read View,這就是我們在 RC 級別下的事務中可以看到別的事務提交的更新的原因。
  • 總之在 RC 隔離級別下,是每個快照讀都會生成并獲取最新的 Read View;而在 RR 隔離級別下,則是同一個事務中的第一個快照讀才會創建 Read View,之后的快照讀獲取的都是同一個 Read View。
  • 正是 RC 每次快照讀,都會形成 Read View,所以 RC 才會有不可重復讀問題。

2、讀-讀

不討論。

?3、寫-寫??

現階段直接理解成都是當前讀,這里不做深究。

4、推薦閱讀?

【MySQL筆記】正確的理解MySQL的MVCC及實現原理_mysqlmvcc實現原理-CSDN博客?

?詳細分析MySQL事務日志(redo log和undo log) - 駿馬金龍 - 博客園 (cnblogs.com)

【MySQL】InnoDB 如何避免臟讀和不可重復讀_innodb怎么解決臟讀-CSDN博客?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/90545.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/90545.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/90545.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

yarn在macOS上的安裝與鏡像源配置:全方位指南

在前端開發領域&#xff0c;高效的包管理工具是提升開發效率的關鍵。yarn 作為一款由 Facebook 推出的包管理器&#xff0c;憑借其快速、可靠、安全的特性&#xff0c;逐漸成為眾多開發者的首選。對于 macOS 用戶而言&#xff0c;正確安裝 yarn 并合理配置鏡像源&#xff0c;能…

Qt 插件架構開發與應用

Qt的插件架構是其模塊化和可擴展性的核心機制之一&#xff0c;它允許開發者通過動態加載插件&#xff08;Plugins&#xff09;擴展應用功能&#xff0c;而無需重新編譯主程序。這種架構廣泛應用于IDE&#xff08;如Qt Creator&#xff09;、媒體播放器&#xff08;解碼器擴展&a…

打破傳統局限:FinOps云成本優化助力企業云成本管理升級

在云計算日益普及的當下,企業紛紛將業務遷移到云端,以期獲得更高效、靈活的IT資源管理方式。然而,云成本管理問題也隨之而來,高額的云支出、資源利用不充分、成本控制難等,成為企業云管理之路上的絆腳石。此時,奇墨科技FinOps云成本優化正以其獨特的優勢,助力企業打破傳統局限,…

HDFS寫性能優化技巧詳解:從理論到實踐

HDFS寫性能優化概述在大數據處理的生態系統中&#xff0c;Hadoop分布式文件系統&#xff08;HDFS&#xff09;作為核心存儲層&#xff0c;其寫性能直接影響著整個數據處理管道的效率。隨著數據規模的指數級增長&#xff0c;企業對HDFS寫入吞吐量和延遲的要求日益嚴苛&#xff0…

基于AutoJawSegment項目的CBCT圖像分割實踐指南

基于AutoJawSegment項目的CBCT圖像分割實踐指南 前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家,覺得好請收藏。點擊跳轉到網站。 1. 項目背景與概述 1.1 CBCT在口腔醫學中的應用 錐形束計算機斷層掃描(Cone Beam Computed Tomograph…

docker部署的ragflow服務遷移 數據卷遷移

[docker ragflow數據遷移]目錄背景一、我的配置文件? 數據存儲路徑一覽&#xff08;基于你的配置文件&#xff09;關于這些 volumes 的說明&#x1f4c1; 如何查看這些卷在本地的具體位置&#xff1f;可能用到的docker 命令如下。&#x1f4e6; 總結建議&#x1f6e0;? 如果想…

Chrome插件學習筆記(三)

Chrome插件學習筆記&#xff08;三&#xff09; 參考文章&#xff1a; https://blog.csdn.net/guoqiankunmiss/article/details/135847091https://blog.csdn.net/guoqiankunmiss/article/details/135974364 1、項目搭建 在前兩篇文章中使用的原生js去操作dom&#xff0c;很費勁…

Android系統中的4KB內存頁簡介

deepseek回答&#xff1a; Android系統中的4KB內存頁是虛擬內存管理的最小單位&#xff0c;其主要用途如下&#xff1a; 一、核心功能 虛擬地址映射 應用程序訪問內存時&#xff0c;系統將虛擬地址按4KB頁框映射到物理內存或磁盤空間&#xff0c;實現進程間的內存隔離和安全訪…

【Chrome】下載chromedriver的地址

下載chromedriver的地址低版本的最新版本的低版本的 http://chromedriver.storage.googleapis.com/index.html 最新版本的 https://googlechromelabs.github.io/chrome-for-testing/#stable

ISP算法——從顏色恒常性到白平衡

前面文章&#xff0c;介紹了人眼感知的物體顏色取決于光源的光譜組成與物體表面的光譜反射特性之間的相互作用。人類視覺的顏色感知是生物機制與認知智能協同作用的結果&#xff0c;人眼視網膜上的視錐細胞檢測光的顏色&#xff0c;視桿細胞分析光的亮度&#xff0c;再共同轉化…

工業缺陷檢測的計算機視覺方法總結

工業缺陷檢測的計算機視覺方法總結 傳統方法 特征提取方式&#xff1a; 顏色&#xff1a;基于HSV/RGB空間分析&#xff0c;如顏色直方圖、顏色矩等紋理&#xff1a;采用LBP、Haar、Gabor濾波器等算子提取紋理模式形狀&#xff1a;基于Hu矩、Zernike矩等數學描述符刻畫幾何特性尺…

js實現宮格布局圖片放大交互動畫

可直接運行代碼 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>五圖交互布局</title><style>* {box-sizing: border-box;margin: 0;padding: 0;}.gallery {display: grid;grid-template-c…

easyexcel流式導出

EasyExcel 支持流式導出&#xff0c;這是它的一個重要特性。流式導出可以有效解決大數據量導出時的內存溢出問題。流式導出的優勢內存友好 &#xff1a;不會一次性將所有數據加載到內存中適合大數據量 &#xff1a;可以處理百萬級甚至更多的數據性能穩定 &#xff1a;內存占用相…

廣州 VR 安全用電技術:工作原理、特性及優勢探析?

&#xff08;一&#xff09;沉浸式學習體驗? 在廣州&#xff0c;VR 用電安全培訓技術給用電安全培訓帶來變革。借助頭戴式顯示設備等硬件&#xff0c;結合 3D 建模和實時渲染技術&#xff0c;打造廣州特色用電場景。員工戴上 VR 設備進入虛擬電力場景&#xff0c;能看到電氣設…

2.Linux 網絡配置

Linux: 網絡配置 版本為centos7 網卡配置文件&#xff1a; /etc/sysconfig/network-scripts/ifcfg-ens33 [rootkami /]# cat /etc/sysconfig/network-scripts/ifcfg-ens33 TYPEEthernet /類型&#xff1a;以太網 PROXY_METHODnone BROWSER_ONLYno BOOTPROTOnone /網絡配…

FPGA Verilog 入門語法指南

FPGA Verilog 入門語法指南 ?? 目錄 Verilog與C語言對比 基礎關鍵字 數據類型 運算符 控制結構 數值表示 阻塞與非阻塞賦值 模塊結構 預處理指令

【鴻蒙HarmonyOS Next App實戰開發】視頻提取音頻

在多媒體處理場景中&#xff0c;經常需要從視頻文件中提取純凈的音頻軌道。本文將介紹如何在HarmonyOS應用中實現這一功能&#xff0c;核心代碼基于ohos/mp4parser庫的FFmpeg能力。 功能概述 我們實現了一個完整的視頻音頻提取頁面&#xff0c;包含以下功能&#xff1a; 通過…

OpenHands:Manus 最強開源平替——本地部署與實戰指南

文章目錄?? 一、OpenHands 核心優勢&#xff1a;為何是 Manus 最佳平替&#xff1f;&#x1f9e0; 二、核心架構解析&#xff1a;多智能體如何協同工作&#xff1f;&#x1f6e0;? 三、本地化部署指南&#xff1a;Docke部署Docker 極速部署&#xff08;推薦&#xff09;&…

用 AI 做數據分析:從“數字”里挖“規律”

數據整理干凈后&#xff0c;就得分析了——算平均值、看差異、找關系&#xff0c;這些都能靠 AI 搞定。這節以“大學生在線學習滿意度”數據為例&#xff0c;教你用 AI 做描述性統計、假設檢驗、相關性分析&#xff0c;一步步從數據里挖規律&#xff0c;超詳細&#xff5e; 1. …

小程序安卓ApK轉aab文件詳情教程MacM4環境

根據Google Play的政策要求&#xff0c;自 2021 年 8 月起&#xff0c;Google Play 將開始要求新應用使用 Android App Bundle&#xff08;以下簡稱aab&#xff09; 進行發布。該格式將取代 APK 作為標準發布格式。 想了解更多關于aab的介紹可以直接閱讀android官方文檔&#x…