MySQL(174)如何理解MySQL的多版本并發控制(MVCC)?

MySQL的多版本并發控制(MVCC, Multi-Version Concurrency Control)是一種用于實現高并發性的機制,它允許多個事務同時讀取和寫入數據,而不會相互阻塞。MVCC主要在InnoDB存儲引擎中實現,通過維護數據的多個版本來實現一致性和隔離性。

一、MVCC的基本原理

MVCC通過維護每行數據的多個版本,使得讀操作不會阻塞寫操作,寫操作也不會阻塞讀操作。它通過以下機制實現:

  1. 隱藏列

    • InnoDB表的每一行都有兩個隱藏列:trx_idroll_pointer
    • trx_id(事務ID)記錄了最近一次修改該行的事務ID。
    • roll_pointer指向回滾段中的上一個版本。
  2. 快照讀

    • 快照讀讀取的是數據的某個版本快照,而不是當前最新版本。它通過檢查每行數據的trx_id和當前事務的ID來決定讀取哪個版本。
    • 快照讀通常用于SELECT語句,不會加鎖。
  3. 當前讀

    • 當前讀讀取的是數據的最新版本,它會對讀取的行加鎖,確保數據的最新性和一致性。
    • 當前讀通常用于SELECT ... FOR UPDATESELECT ... LOCK IN SHARE MODE語句。

二、事務隔離級別與MVCC

MVCC在不同的事務隔離級別下有不同的表現:

  1. 讀未提交(READ UNCOMMITTED)

    • 事務可以讀取其他事務未提交的數據(臟讀)。
    • 不適用MVCC。
  2. 讀已提交(READ COMMITTED)

    • 事務只能讀取其他事務已提交的數據。
    • 每次讀取數據時,會讀取最新的已提交版本。
  3. 可重復讀(REPEATABLE READ)

    • 事務在開始時創建一個一致性視圖,所有讀取操作都基于這個視圖。
    • 事務進行過程中,即使其他事務已提交,也不會看到這些修改。
    • 防止不可重復讀和幻讀。
  4. 序列化(SERIALIZABLE)

    • 最嚴格的隔離級別,事務完全串行化執行。
    • 會對讀取的每一行數據加鎖。

三、示例代碼

以下是一些示例代碼,展示了在不同隔離級別下,使用MVCC如何避免讀寫沖突。

1. 創建測試表并插入數據
CREATE TABLE test_mvcc (id INT PRIMARY KEY,value VARCHAR(50)
);INSERT INTO test_mvcc (id, value) VALUES (1, 'Initial Value');
2. 設置事務隔離級別并啟動事務
-- 在會話1中(事務1)
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
START TRANSACTION;-- 在會話2中(事務2)
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
START TRANSACTION;
3. 快照讀示例
-- 在會話1中,讀取數據
SELECT * FROM test_mvcc WHERE id = 1;-- 在會話2中,更新數據
UPDATE test_mvcc SET value = 'Updated Value' WHERE id = 1;-- 在會話1中,再次讀取數據
SELECT * FROM test_mvcc WHERE id = 1;-- 此時,會話1中的兩次讀取結果都是 'Initial Value',因為使用的是快照讀
4. 當前讀示例
-- 在會話1中,使用當前讀讀取數據
SELECT * FROM test_mvcc WHERE id = 1 FOR UPDATE;-- 在會話2中,嘗試更新數據
UPDATE test_mvcc SET value = 'Another Update' WHERE id = 1;-- 會話2中的更新操作會被阻塞,直到會話1提交或回滾事務
5. 提交事務
-- 在會話1中,提交事務
COMMIT;-- 在會話2中,更新操作解除阻塞,繼續執行
UPDATE test_mvcc SET value = 'Another Update' WHERE id = 1;

四、Java代碼示例

以下是一個Java示例程序,展示了如何通過JDBC設置事務隔離級別,并展示使用MVCC的效果。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;public class MVCCExample {private static final String JDBC_URL = "jdbc:mysql://localhost:3306/your_database";private static final String USER = "your_db_user";private static final String PASSWORD = "your_db_password";public static void main(String[] args) {try (Connection connection1 = DriverManager.getConnection(JDBC_URL, USER, PASSWORD);Connection connection2 = DriverManager.getConnection(JDBC_URL, USER, PASSWORD)) {connection1.setAutoCommit(false);connection2.setAutoCommit(false);// 設置事務隔離級別為 REPEATABLE READconnection1.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);connection2.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);// 在會話1中讀取數據try (Statement statement1 = connection1.createStatement()) {ResultSet rs1 = statement1.executeQuery("SELECT value FROM test_mvcc WHERE id = 1");while (rs1.next()) {System.out.println("Session 1 - Initial Value: " + rs1.getString("value"));}}// 在會話2中更新數據try (Statement statement2 = connection2.createStatement()) {statement2.executeUpdate("UPDATE test_mvcc SET value = 'Updated Value' WHERE id = 1");}// 在會話1中再次讀取數據try (Statement statement1 = connection1.createStatement()) {ResultSet rs1 = statement1.executeQuery("SELECT value FROM test_mvcc WHERE id = 1");while (rs1.next()) {System.out.println("Session 1 - After Update in Session 2: " + rs1.getString("value"));}}// 提交會話2connection2.commit();// 在會話1中再次讀取數據(驗證隔離級別的效果)try (Statement statement1 = connection1.createStatement()) {ResultSet rs1 = statement1.executeQuery("SELECT value FROM test_mvcc WHERE id = 1");while (rs1.next()) {System.out.println("Session 1 - After Commit in Session 2: " + rs1.getString("value"));}}// 提交會話1connection1.commit();} catch (SQLException e) {e.printStackTrace();}}
}

五、總結

MySQL的MVCC通過維護多個數據版本實現高并發性和一致性,使得讀操作和寫操作可以并行執行而不會互相阻塞。理解MVCC的工作原理,對于設計高性能、高并發的數據庫應用至關重要。通過示例代碼,我們可以看到在不同事務隔離級別下,MVCC如何幫助我們實現并發控制和數據一致性。

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

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

相關文章

Docker--將非root用戶添加docker用戶組,解決頻繁sudo執行輸入密碼的問題

一、為什么要有docker用戶組? 根本原因: Linux的設備訪問權限控制機制 Docker守護進程(dockerd)運行時會創建一個特殊的Unix套接字文件,如:/var/run/docker.sock。 這個文件就像一個“門”,所有…

C語言---函數的遞歸與迭代

遞歸的理解與限制條件 所謂函數遞歸就是遞推加回歸的過程,就是函數自己調用自己。遞歸的思想就是把復雜的問題拆分成與原來那個大問題相似的子問題來求解,大事化小,像剝洋蔥一樣,最終把問題解決。 遞歸的限制條件: 一個…

freqtrade在docker運行一個dryrun實例

檢查配置 freqtrade trade --config user_data/config.json --strategy MlStrategy config文件,這個配置做期貨為主,靜態配置了交易對,同時端口和第一個bot要不一樣,不然沒有辦法進行監控,甚至要沖突了。10S鐘進行循環&#xff0c…

單片機學習筆記.PWM

PWM原理: 頻率占空比:精度占空比變化步距 電機驅動電路:利用PWM實現呼吸燈代碼 sbit LEDP2^0;//引腳定義unsigned char Time,i;//變量定義void Delay(unsigned int t)//定義延時 {while(t--); }main函數里:int main() {unsigned c…

【Git】解決使用SSH連接遠程倉庫時需要多次輸入密碼的問題

問題產生的原因:你的SSH私鑰設置了密碼短語(passphrase)。解決問題的方法:使用SSH代理(ssh-agent),ssh-agent是一個后臺運行程序,它會記住你解鎖過的SSH私鑰的密碼短語,這…

機器學習—邏輯回歸

一介紹邏輯回歸是處理二分類問題的線性模型,通過sigmoid函數將線性輸出映射到[0,1],輸出事件發生概率,廣泛用于預測與分類。如果做坐標的話,特征就是p1和p2,結果就是y紅的與綠的 二Sigma函數代碼說明Sigmoid 函數定義&…

深入解讀OpenTelemetry分布式鏈路追蹤:原理與實踐指南

深入解讀OpenTelemetry分布式鏈路追蹤:原理與實踐指南 分布式系統在微服務架構下,服務調用鏈越來越復雜,追蹤單次請求在各個微服務之間的執行情況成為運維與性能優化的關鍵。作為新一代開源標準,OpenTelemetry為分布式追蹤、指標與…

【0基礎PS】PS工具詳解--圖案圖章工具

目錄前言一、圖案圖章工具基礎認知?二、工具選項欄參數詳解?三、圖案圖章工具應用案例?總結前言 在 Adobe Photoshop 這一強大的圖像處理軟件中,圖案圖章工具是一個獨具特色的功能,它允許用戶利用預先定義好的圖案進行繪畫操作。 一、圖案圖章工具基…

劇本殺小程序系統開發:構建數字化劇本殺生態圈

在快節奏的現代生活中,人們越來越渴望在閑暇之余找到一種既能放松心情又能增進社交的方式。劇本殺,作為一種集推理、表演、社交于一體的新興娛樂形式,恰好滿足了這一需求。然而,隨著市場的不斷擴大,如何保持劇本殺的新…

【DL學習筆記】計算圖與自動求導

計算圖計算圖(Computation Graph)是一種用于描述計算過程的圖形化表示方法。在深度學習中,計算圖通常用于描述 網絡結構、運算過程 和數據流向。計算圖是一種有向無環圖,用圖形方式來表示算子與變量之間的關系,直觀高效…

大型地面光伏電站開發建設流程

?地面電站特特點:規模大,通常占用土地、水面等,地面式選址選項多,且不斷拓展出新的用地模式,地面式選址集中在山體、灘涂、沼澤、戈壁、沙漠、受污染土地等閑置或廢棄土地上。

除數博弈(動態規劃)

愛麗絲和鮑勃一起玩游戲&#xff0c;他們輪流行動。愛麗絲先手開局。最初&#xff0c;黑板上有一個數字 n 。在每個玩家的回合&#xff0c;玩家需要執行以下操作&#xff1a;選出任一 x&#xff0c;滿足 0 < x < n 且 n % x 0 。用 n - x 替換黑板上的數字 n 。如果玩家…

一起學springAI系列一:初體驗

Spring AI是干嘛的官網最權威&#xff0c;直接粘貼&#xff1a;“Spring AI”項目旨在簡化那些包含人工智能功能的應用程序的開發過程&#xff0c;同時避免不必要的復雜性。AI相關領域的功能對python的支持是最好的&#xff0c;相關供應商在出了啥功能的時候&#xff0c;都會優…

Ext JS極速項目之 Coworkee

ExtJS Coworkee 是什么? Ext JS 的 Coworkee 是一個由 Sencha 官方提供的完整員工管理應用示例,旨在展示 Ext JS 框架在企業級應用開發中的能力。 在線試用的地址是: https://examples.sencha.com/coworkee/#home 頁面效果與布局 登錄頁面: 主頁效果 左右分區結構:左…

飛算科技:原創技術重塑 Java 開發,引領行業數智化新浪潮

在科技革新的浪潮中&#xff0c;飛算科技作為一家堅持自主創新的數字科技企業&#xff0c;同時也是國家級高新技術企業&#xff0c;正深耕互聯網科技、大數據、人工智能等前沿領域&#xff0c;為眾多企業的數字化與智能化轉型提供強勁動力。?飛算科技的成長軌跡&#xff0c;是…

cesium FBO(一)渲染到紋理(RTT)

一聽到三維的RTT&#xff08;Render To Texture&#xff09;&#xff0c;似乎很神秘&#xff0c;但從底層實現一看&#xff0c;其實也就那樣&#xff0c;設計API的哪些頂級家伙已經幫你安排的明明白白了&#xff0c;咱們只需要學會怎么用就可以了。我認為得從WebGL入手&#xf…

PNP機器人機器人學術年會展示靈巧手動作捕捉方案。

2025年8月1-3日&#xff0c;第六屆中國機器人學術年會&#xff08;CCRS2025&#xff09;在長沙國際會議中心舉行&#xff0c;主題“人機共融&#xff0c;智向未來”。PNP機器人與靈巧智能聯合展出最新靈巧手模仿學習方案&#xff1a;基于少量示教數據即可快速復現復雜抓取動作&…

【45】C#入門到精通——C#調用C/C++生成動態庫.dll及C++ 生成動態庫.dll ,DllImport()方式導入 C++動態庫.dll方法總結

文章目錄1 C 生成動態庫.dll2 C#調用C/C生成動態庫.dll2.1 [DllImport()] 方式導入 C動態庫.dll2.2 調用測試3 C/C 生成通用dll,改進3.1改進后.h3.2 .cpp3.2 C# 調用4 [DllImport()] 方式導入C生成的 .dll 總結4.1 指定路徑導入4.2 .dll放在 執行目錄下&#xff08;一定要放對&…

從協議棧到ath12k_mac_op_tx的完整調用路徑

文章目錄 從協議棧到ath12k_mac_op_tx的完整調用路徑 1. 整體架構概覽 2. 詳細調用路徑分析 2.1 應用層到Socket層 2.2 協議層處理 2.3 網絡設備層到mac80211 2.4 mac80211發送入口 2.5 mac80211核心發送處理 2.6 mac80211發送核心處理 2.7 mac80211發送調度 2.8 最終驅動調用 …

WPFC#超市管理系統(4)入庫管理

入庫管理7. 商品入庫管理7.2 入庫實現顯示名稱、圖片、單位7.3 界面設計7.3 功能實現7. 商品入庫管理 數據庫中StockRecord表需要增加商品出入庫Type類型為nvarchar(50)。C#中的數據庫重新同步StockRecord表在Entity→Model中新建枚舉類型StockType namespace 超市管理系統.E…