中間件專欄之MySQL篇——MySQL事務原理、鎖機制分析

MySQL的事務性也是其重要特性之一。

什么是事務:事務的本質是并發控制的單元,是用戶定義的一個操作序列。這些操作要么都做,要么都不做,是 一個不可分割的工作單位。

目的:事務的目的在于將數據庫從一種一致性狀態轉換為另一種一致性狀態,保證系統始終處于一個完整且正確的狀態。

組成:事務可由一條非常簡單的 SQL 語句組成,也可以由一組復雜的 SQL 語句組成。

特征:在數據庫提交事務時,可以確保要么所有修改都已經保存,要么所有修改都不保存; 事務是訪問并更新數據庫各種數據項的一個程序執行單元。

事務控制語句:

-- 顯示開啟事務
START TRANSACTION | BEGIN-- 提交事務,并使得已對數據庫做的所有修改持久化
COMMIT-- 回滾事務,結束用戶的事務,并撤銷正在進行的所有未提交的修改
ROLLBACK-- 創建一個保存點,一個事務可以有多個保存點
SAVEPOINT identifier-- 刪除一個保存點
RELEASE SAVEPOINT identifier-- 事務回滾到保存點
ROLLBACK TO [SAVEPOINT] identifier

一、事務的ACID特性

1. ACID 四大特性

特性描述作用
A(原子性,Atomicity)事務是不可分割的最小工作單元,要么全部執行成功,要么全部回滾。確保事務中所有 SQL 語句要么都成功,要么都失敗
C(一致性,Consistency)事務執行前后,數據庫必須保持一致狀態,不會破壞數據的完整性。保證數據在事務開始和結束后滿足所有約束,如外鍵、唯一性等。
I(隔離性,Isolation)多個事務同時執行時,彼此不會相互影響,避免臟讀、幻讀等問題。MySQL 通過不同的隔離級別控制事務之間的可見性。
D(持久性,Durability)事務一旦提交,數據就會永久存儲,即使系統崩潰也不會丟失。通過 redo logbinlog 保證事務的持久性。

2. ACID 詳解

2.1 原子性(Atomicity)

? 事務必須是不可分割的整體

  • 如果某個操作失敗,事務會回滾,撤銷所有已執行的操作。
  • MySQL 通過 UNDO LOG(回滾日志)實現回滾機制

? 示例

START TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE id = 1; 
UPDATE accounts SET balance = balance + 100 WHERE id = 2; 
ROLLBACK; -- 撤銷所有操作

🔹 如果發生錯誤或斷電,所有已執行的 SQL 語句都會被回滾,保證賬戶數據不丟失。


2.2 一致性(Consistency)

? 事務執行前后,數據必須滿足完整性約束

  • 事務不能破壞數據庫的外鍵約束、唯一性約束等規則。

? 示例 假設 accounts 表規定 balance >= 0,那么:

START TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;

🔹 如果某個賬戶余額變成負數,事務必須回滾,保持數據一致性


2.3 隔離性(Isolation)

? 多個事務并發執行時,彼此的修改互不影響

  • 解決臟讀、不可重復讀、幻讀等問題。
  • MySQL 提供 四種事務隔離級別
    1. READ UNCOMMITTED(讀未提交) → 允許讀取未提交數據,可能導致臟讀
    2. READ COMMITTED(讀已提交) → 只能讀取已提交數據,但可能出現不可重復讀
    3. REPEATABLE READ(可重復讀,MySQL 默認) → 多次查詢結果一致,避免不可重復讀
    4. SERIALIZABLE(可串行化) → 最高隔離級別,強制事務串行執行,性能最低

? 示例

SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
START TRANSACTION;
SELECT balance FROM accounts WHERE id = 1; -- 第一次讀取
-- 其他事務修改 balance
SELECT balance FROM accounts WHERE id = 1; -- 仍然是原來的值
COMMIT;

🔹 可重復讀(默認)能保證第二次查詢仍然返回原始數據,避免不可重復讀問題


2.4 持久性(Durability)

? 事務一旦提交,數據就必須永久存儲

  • MySQL 通過 Redo Log(重做日志) 和 Binlog(二進制日志) 記錄已提交的事務。
  • 即使服務器崩潰,重啟后 MySQL 也能恢復數據

? 示例

START TRANSACTION;
UPDATE orders SET status = 'shipped' WHERE id = 123;
COMMIT; -- 事務提交后數據不會丟失

🔹 即使 MySQL 崩潰,訂單狀態仍然是 shipped

二、四大隔離級別詳解

1. MySQL 四大事務隔離級別

MySQL 提供四種 事務隔離級別(由低到高):

隔離級別臟讀不可重復讀幻讀性能SQL 設置
READ UNCOMMITTED(讀未提交)? 可能? 可能? 可能? 性能最高SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
READ COMMITTED(讀已提交)? 不可能? 可能? 可能? 適中SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
REPEATABLE READ(可重復讀)MySQL 默認? 不可能? 不可能? 可能? 適中SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SERIALIZABLE(可串行化)? 不可能? 不可能? 不可能? 性能最低SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

? = 解決了該問題
? = 可能出現該問題


2. 事務隔離級別問題詳解

2.1 臟讀(Dirty Read)

定義:一個事務可以讀取到另一個未提交事務的修改。如果該事務回滾,則讀取到的數據是無效的,造成數據不一致。

示例

  1. 事務 A 修改 balance = 1000 → 500(但未提交)。
  2. 事務 B 讀取 balance = 500(但事務 A 可能回滾)。
  3. 事務 A 回滾balance 變回 1000,但事務 B 讀到了錯誤的數據。

? 解決方法

  • READ COMMITTED 及以上級別可以避免臟讀。

2.2 不可重復讀(Non-Repeatable Read)

定義:同一事務內多次查詢同一條記錄,但結果不一致,因為另一個事務修改并提交了數據

示例

  1. 事務 A 讀取 balance = 1000
  2. 事務 B 修改并提交 balance = 500
  3. 事務 A 再次讀取 balance,發現變成 500,數據發生變化。

? 解決方法

  • REPEATABLE READ 及以上級別可以避免不可重復讀。

2.3 幻讀(Phantom Read)

定義:一個事務內多次查詢相同條件的數據,但結果不一致,因為另一個事務插入/刪除了數據

示例

  1. 事務 A 運行 SELECT * FROM users WHERE age > 30;,返回 5 條數據。
  2. 事務 B 插入 一條 age > 30 的數據并提交。
  3. 事務 A 再次運行 相同查詢,返回 6 條數據,發生幻讀。

? 解決方法

  • SERIALIZABLE 級別可以避免幻讀(使用表級鎖)。
  • InnoDB 默認通過 GAP 鎖避免幻讀

3. 事務隔離級別總結

隔離級別適用場景優缺點
READ UNCOMMITTED(讀未提交)允許最高并發,但數據不安全可能發生臟讀、不可重復讀、幻讀
READ COMMITTED(讀已提交)大部分數據庫的默認級別(如 Oracle),保證讀到已提交數據可能發生不可重復讀、幻讀
REPEATABLE READ(可重復讀)MySQL 默認適合大多數應用,保證同一事務多次讀取結果一致可能發生幻讀
SERIALIZABLE(可串行化)最高級別,數據最安全,所有事務串行執行

性能最低,適用于高安全性應用

三、MVCC詳解

1. 什么是 MVCC(多版本并發控制)?

MVCC(Multi-Version Concurrency Control,多版本并發控制)是一種并發控制機制,可以讓多個事務無鎖并發執行,提高數據庫性能,同時避免臟讀、不可重復讀等問題。

  • MVCC 主要用于 InnoDB 存儲引擎,默認支持 REPEATABLE READ 隔離級別。
  • 通過 數據行的多個版本,使得讀操作不會被寫操作阻塞,提升并發性能。

2. MVCC 解決了哪些問題?

? 避免臟讀:事務只能讀取已經提交的數據。
? 避免不可重復讀:在同一事務內,多次讀取相同數據,結果保持一致。
? 提高并發性能:讀操作無需加鎖,避免鎖競爭。

? 無法解決幻讀:MVCC 無法防止插入數據帶來的幻讀,需要使用 GAP 鎖


3. MVCC 的實現原理

3.1 MVCC 依賴的關鍵機制

MVCC 在 InnoDB 中主要依賴以下 三個重要的存儲結構

  1. 隱藏列(隱式事務 ID 和回滾指針)
  2. Undo Log(回滾日志)
  3. Read View(讀視圖)

3.2 MVCC 關鍵實現細節

(1)隱藏列

InnoDB 為每個數據行額外存儲兩個隱藏列

  • trx_id:記錄插入/修改該行的事務 ID。
  • roll_pointer:指向 Undo Log,可通過回滾日志獲取數據的舊版本。

(2)Undo Log(回滾日志)
  • 作用:存儲舊版本數據,使得歷史版本可讀(多版本存儲)。
  • 實現
    • 每次 UPDATEDELETE,都會把舊值存入 Undo Log,并更新 roll_pointer 指向舊版本數據。
    • 事務回滾時,Undo Log 可用于恢復舊數據

(3)Read View(讀視圖)
  • 作用:控制事務可見性,決定事務是否可以看到某個版本的數據。
  • 核心邏輯
    1. 事務 T1 開啟時,會生成 Read View(包含當前活躍事務的 trx_id 列表)。
    2. 查詢數據時:
      • trx_id 小于 Read View 最小活躍事務 ? → 可見(數據已提交)。
      • trx_id 在活躍事務范圍內 ? → 不可見(數據未提交)。
      • trx_id 大于當前事務 ID ? → 不可見(數據由新事務插入)。
    3. 事務 T1 只能看到 Read View 創建時的數據快照,即快照讀

4. MVCC 讀寫方式

(1)快照讀(Snapshot Read)

  • 讀取的是數據的歷史版本不加鎖,提高查詢性能。
  • 適用 SQL
  • 實現方式
    • Read View 讀取符合當前事務可見性的數據。
    • Undo Log 提供歷史版本數據。

(2)當前讀(Current Read)

  • 讀取的是最新版本數據,會加鎖
  • 適用 SQL(需要保證數據一致性)
  • 實現方式
    • 事務需要讀取最新版本數據,并阻塞其他事務修改該數據

5. MVCC 在不同隔離級別下的行為

隔離級別快照讀當前讀
READ UNCOMMITTED(讀未提交)讀取未提交的數據(不安全)直接讀取最新版本
READ COMMITTED(讀已提交)讀取最新已提交版本加鎖,讀取最新數據
REPEATABLE READ(可重復讀,MySQL 默認)同一事務內,多次查詢結果一致加鎖,讀取最新數據
SERIALIZABLE(可串行化)強制事務串行執行加鎖,阻塞其他事務

6. MVCC 適用范圍

? 適用于 InnoDB 表(默認支持 MVCC)。
? 不適用于 MyISAM(MyISAM 不支持事務,不會存儲多個數據版本)。
? 不適用于 SERIALIZABLE 級別(MVCC 失效,會強制加鎖)。


7. MVCC 總結

機制作用
隱藏列(trx_id、roll_pointer)記錄事務 ID、舊數據指針
Undo Log(回滾日志)存儲數據的歷史版本
Read View(讀視圖)確定事務可見性,控制快照讀

MVCC 優勢

? 讀操作不加鎖,并發性能高。
? 保證事務隔離性,避免臟讀、不可重復讀問題。

MVCC 局限

? 需要存儲多個版本的數據,占用空間。
? 無法避免幻讀(需要GAP 鎖)。

適用場景

? OLTP(高并發事務處理)場景,如 銀行系統、電商訂單管理
? 查詢頻繁但更新少的系統,如 分析報表

MVCC 是 MySQL 高性能事務控制的核心,合理利用 MVCC 機制,可以大幅提升數據庫性能,同時保證數據一致性!

四、MySQL中鎖機制

?

MySQL 的鎖機制用于控制多個事務并發訪問數據庫時的數據一致性和并發性。不同的存儲引擎(如 InnoDBMyISAM)實現的鎖機制有所不同,InnoDB 采用更細粒度的鎖控制,并支持 行級鎖表級鎖意向鎖 等。


1. MySQL 鎖的分類

MySQL 的鎖可分為 全局鎖表級鎖行級鎖,其中行級鎖又包括共享鎖、排他鎖、意向鎖、間隙鎖等。

鎖類型適用范圍特點
全局鎖作用于整個數據庫FLUSH TABLES WITH READ LOCK,適用于備份數據,影響所有操作。
表級鎖作用于整張表LOCK TABLES,如 MyISAM 存儲引擎使用表鎖,事務并發能力低。
行級鎖作用于單行數據InnoDB 支持,提供更高的并發性能,但需要管理更多的鎖信息。

2. MySQL 表級鎖

2.1 表鎖(Table Lock)

適用于 MyISAM,每次鎖定整個表,不支持行級鎖

操作SQL 語句特性
加讀鎖(共享鎖)LOCK TABLES users READ;其他線程可讀,但不可寫
加寫鎖(排他鎖)LOCK TABLES users WRITE;其他線程不可讀也不可寫
釋放表鎖UNLOCK TABLES;釋放鎖,其他事務可訪問

? 缺點:影響并發,大多數情況下不推薦使用


3. MySQL 行級鎖

3.1 共享鎖(S 鎖,Shared Lock)

  • 多個事務可同時讀取數據,但不能修改數據
  • 適用于 SELECT ... LOCK IN SHARE MODE

🔹 應用場景:如果多個事務需要并發讀取數據,并且不希望數據被修改,可使用共享鎖。?

3.2 排他鎖(X 鎖,Exclusive Lock)

  • 排他性強,其他事務不能讀取或修改被鎖定的行
  • 適用于 SELECT ... FOR UPDATE

🔹 應用場景:用于更新前的查詢,確保數據在更新前不會被其他事務修改。?

3.3 意向鎖(Intent Lock)

  • 自動加鎖,用于標識事務希望獲取行級鎖,防止表鎖和行鎖沖突。
  • InnoDB 自動管理,開發者無需手動控制
鎖類型作用
意向共享鎖(IS,Intent Shared)事務想要加 S 鎖,表級鎖不能加 X 鎖
意向排他鎖(IX,Intent Exclusive)事務想要加 X 鎖,表級鎖不能加 S/X 鎖

🔹 應用場景:防止表級鎖與行級鎖沖突,提高鎖管理效率。


3.4 間隙鎖(Gap Lock,防止幻讀)

作用:防止幻讀,用于 REPEATABLE READ 隔離級別。

🔹 應用場景:當事務查詢 age BETWEEN 18 AND 25 時,即使不存在數據,InnoDB 仍會鎖住范圍,防止其他事務插入 age=20 的新數據。


3.5 Next-Key Lock(間隙鎖 + 行鎖)

  • 鎖定一行數據及其范圍,防止新數據插入。
  • InnoDB 在 REPEATABLE READ 級別下默認使用,避免幻讀。

🔹 如果 id=10 存在,InnoDB 不僅鎖定該行,還會鎖定 id=10 之后的索引范圍**,防止插入新記錄。


4. 死鎖(Deadlock)及避免方法

4.1 什么是死鎖?

死鎖是指兩個或多個事務互相等待對方釋放鎖,導致事務無法繼續執行。

4.2 如何避免死鎖?

方法策略
固定訪問順序保證所有事務按照相同順序訪問資源,避免循環等待。
減少鎖的持有時間及時提交事務,避免長時間持有鎖。
使用較高的隔離級別SERIALIZABLE 可以減少并發,避免復雜死鎖。
索引優化減少鎖定的行數,優化 WHERE 條件,避免鎖住大量數據。

總結

鎖類型作用適用存儲引擎
全局鎖鎖住整個數據庫,影響所有操作所有存儲引擎
表級鎖鎖住整張表,適用于 MyISAMMyISAM,InnoDB
行級鎖只鎖住特定行,提高并發性能InnoDB
共享鎖(S 鎖)允許讀取,不允許修改InnoDB
排他鎖(X 鎖)其他事務不能讀也不能寫InnoDB
意向鎖(IS/IX)防止表級鎖和行級鎖沖突InnoDB
間隙鎖(Gap Lock)防止幻讀,鎖定范圍InnoDB
Next-Key Lock行鎖 + 間隙鎖,避免幻讀InnoDB

?

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

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

相關文章

機器學習的三個基本要素

機器學習的基本要素包括模型、學習準則(策略)和優化算法三個部分。機器學習方法之間的不同,主要來自其模型、學習準則(策略)、優化算法的不同。 模型 機器學習首要考慮的問題是學習什么樣的模型(Model&am…

集成方案 | Docusign 能與哪些應用程序集成?

如何實現 Docusign 與多種系統平臺之間的高效集成? 在企業跨境簽約場景中,員工常常需要在電子簽系統與辦公應用(如釘釘、企業微信)、CRM、ERP 等系統之間來回切換,手動上傳合同、下載簽署文件并同步數據。這種繁瑣的操…

2025華為OD機試真題目錄【E卷+A卷+B卷+C卷+D卷】持續收錄中...

摘要 本專欄提供2025最新最全的華為OD機試真題庫(EABCD卷),包括100分和200分題型。題目包含題目描述、輸入描述、用例、備注和解題思路、多種語言解法(Java/JS/Py/C/C)。希望小伙伴們認真學習、順利通過。 聲明 本專…

廣域互聯網關鍵技術詳解(GRE/LSTP/IPsec/NAT/SAC/SPR)

《廣域互聯網關鍵技術詳解》屬于博主的“廣域網”專欄,若想成為HCIE,對于廣域網相關的知識需要非常了解,更多關于廣域網的內容博主會更新在“廣域網”專欄里,請持續關注! 一.前言 廣域互聯技術紛雜多樣,不…

AF3 _correct_post_merged_feats函數解讀

AlphaFold3 msa_pairing 模塊的 _correct_post_merged_feats 函數用于對合并后的特征進行修正,確保它們符合預期的格式和要求。這包括可能的對特征值進行調整或進一步的格式化,確保合并后的 FeatureDict 適合于后續模型的輸入。 主要作用是: 在多鏈蛋白質 MSA(多序列比對)…

Docker 學習(三)——數據管理

容器中的管理數據主要有兩種方式: 數據卷 (Data Volumes): 容器內數據直接映射到本地主機環境; 數據 卷容器( Data Volume Containers): 使用特定容器維護數據卷 1.數據卷 數據卷…

基于SSM+Vue+uniapp的考研交流(帶商城)小程序+LW示例參考

系列文章目錄 1.基于SSM的洗衣房管理系統原生微信小程序LW參考示例 2.基于SpringBoot的寵物攝影網站管理系統LW參考示例 3.基于SpringBootVue的企業人事管理系統LW參考示例 4.基于SSM的高校實驗室管理系統LW參考示例 5.基于SpringBoot的二手數碼回收系統原生微信小程序LW參考示…

2025-03-04 學習記錄--C/C++-PTA 練習5-3 字符金字塔

合抱之木,生于毫末;九層之臺,起于累土;千里之行,始于足下。💪🏻 一、題目描述 ?? 二、解題步驟 ?? 第1步、把字符和一個空格看作整體,即"G_"; 第2步、外…

DeepSeek集成到VScode工具,讓編程更高效

DeepSeek與VScode的強強聯合,為編程效率樹立了新標桿。 DeepSeek,一款卓越的代碼搜索引擎,以其精準的索引和高速的檢索能力,助力開發者在浩瀚的代碼海洋中迅速定位關鍵信息。 集成至VScode后,開發者無需離開熟悉的編輯…

前端-css(預編譯器sass)

1.sass(scss->sass第三代) Sass3 -> Scss(Sassy CSS),SCSS(Sassy CSS) 是 CSS 語法的擴展. 2.scss注釋 Sass 支持標準的 CSS 多行注釋 /* */,以及單行注釋 //,前者會 被完整輸出到編譯后的 CSS 文件中,而后者則不會 3.scss定義變量 …

【計算機網絡入門】初學計算機網絡(十一)重要

目錄 1. CIDR無分類編址 1.1 CIDR的子網劃分 1.1.1 定長子網劃分 1.1.2 變長子網劃分 2. 路由聚合 2.1 最長前綴匹配原則 3. 網絡地址轉換NAT 3.1 端口號 3.2 IP地址不夠用? 3.3 公網IP和內網IP 3.4 NAT作用 4. ARP協議 4.1 如何利用IP地址找到MAC地址…

Android 獲取jks的SHA1值:java.io.IOException: Invalid keystore format

命令生成 keytool -list -v -keystore 全路徑.jks -alias 別名 -storepass 密碼 -keypass 密碼 1、遇到 的問題: 通過快捷鍵 ‘win r’ 啟動的小黑框運行上面的命令會出現下面這個錯誤keytool 錯誤: java.io.IOException: Invalid keystore format 2、解決問題 …

掌握 ElasticSearch 聚合查詢:Aggregations 入門與實戰

掌握 ElasticSearch 聚合查詢:Aggregations 入門與實戰 一、引言 (Introduction)二、數據準備 (Data Preparation)2.1 創建索引 (Create Index)2.2 批量導入數據 (Bulk Import Data) 三、聚合查詢基礎 (Aggregation Basics)3.1 什么是聚合查詢?(What are…

Microsoft.Office.Interop.Excel 的簡單操作

Microsoft.Office.Interop.Excel 的簡單操作 1、安裝 Microsoft.Office.Interop.Excel2、聲明引用 Microsoft.Office.Interop.Excel3、簡單的新建 EXCEL 操作代碼4、將 DataGridView 表數據寫到 EXCEL 操作代碼5、將 EXCEL 表數據讀取到 C# 數據表 DataTable 操作代碼 1、安裝 …

LLM 對話框組件 | 字節青訓營前端開發項目

系統介紹 LLM對話框項目系統介紹 一、項目概述 選題背景隨著人工智能技術的飛速發展,自然語言處理(NLP)領域取得了顯著進展,其中對話系統(Dialog System)作為NLP的重要應用方向,正逐漸滲透到人們的日常生活中。從智能客服到語音助手,從智能家居到在線教育,對話系統以…

k8s命名空間和資源配額

在現代的云計算環境中,容器化技術已成為主流。而 Kubernetes(簡稱 k8s)作為一項開源的容器編排系統,廣泛應用于各類場景。本文將詳細介紹關于 k8s 中的命名空間和資源配額,幫助你更好地理解和管理你的集群資源。 k8s …

從統計學視角看機器學習的訓練與推理

從統計學視角看機器學習的訓練與推理 目錄 引言:統計學與機器學習的奇妙緣分訓練與推理:你得先學會“看數據”再“用數據”最大似然估計(MLE):從直覺到數學證明 3.1 伯努利分布的MLE3.2 單變量高斯分布的MLE3.3 多元…

AI賦能企業協作4-NL2Sql技術路線

1.1 對話即服務的一點思考 在數智化轉型的過程中,基于即時通信(IM)的協作平臺正悄然成為企業智能化轉型的“新基建”。協作平臺天然具備高頻交互、實時協同和場景化落地的特性,仿佛是為對話式AI量身定制的試驗場——員工在熟悉的聊…

批量提取 Word 文檔中的頁面

如何將 Word 文檔中的頁面提取出來形成一個新的文檔呢?比如將 Word 文檔中的第一頁提取出來、將 Word 文檔中的最后一頁提取出來、再或者將 Word 文檔中的中間幾頁提取出來等等。人工的處理肯定非常的麻煩,需要新建 Word 文檔,然后將內容復制…

Sqlserver安全篇之_啟用TLS即配置SQL Server 數據庫引擎以加密連接

官方文檔 https://learn.microsoft.com/zh-cn/sql/database-engine/configure-windows/configure-sql-server-encryption?viewsql-server-ver16 https://learn.microsoft.com/zh-cn/sql/database-engine/configure-windows/manage-certificates?viewsql-server-ver15&pre…