MySQL中的鎖機制

来源:https://www.cnblogs.com/cnqijian/archive/2023/08/14/17627639.html
-Advertisement-
Play Games

> 拋磚引玉:多個查詢需要在同一時刻進行數據的修改,就會產生併發控制的問題。我們需要如何避免寫個問題從而保證我們的資料庫數據不會被破壞。 ## 鎖的概念 讀鎖是共用的互相不阻塞的。多個事務在聽一時刻可以同時讀取同一資源,而相互不幹擾。 寫鎖的排他的。一個寫鎖會阻塞其他寫鎖或讀鎖。出於安全考慮只有這樣 ...


拋磚引玉:多個查詢需要在同一時刻進行數據的修改,就會產生併發控制的問題。我們需要如何避免寫個問題從而保證我們的資料庫數據不會被破壞。

鎖的概念

讀鎖是共用的互相不阻塞的。多個事務在聽一時刻可以同時讀取同一資源,而相互不幹擾。

寫鎖的排他的。一個寫鎖會阻塞其他寫鎖或讀鎖。出於安全考慮只有這樣才能保證在給定的時間里只有一個事務能夠執行寫入,並防止其他事務讀取正寫入的同一資源。

鎖帶來的問題

通過鎖定機制可以實現事務的隔離性要求,使得事務可以併發的工作,同時也帶來了三個問題:臟讀,不可重覆讀和丟失更新。

臟讀

臟數據:未提交的數據

如果讀到了臟數據即一個事務可以讀取到另一個事務中未提交的數據那就違背了事務的隔離性。

所以臟讀是指在不同的事務下,當前事務可以讀取到另外事務的未提交的數據,簡單來說就是可以讀取到臟數據。

演示:

初始狀態:

image-20230813233401790

將會話A,B設置隔離級別為RU

set session transaction isolation level READ UNCOMMITTED;

image-20230813235156382

會話A插入一條數據

image-20230814000655870

這時候事務B在此執行查詢操作,會發現事務B讀取到了事務A新增的數據。註意:此時事務A沒有提交。

image-20230814000932266

不可重覆讀

在一個事務中兩次讀取到的數據是不一樣的,這中情況被稱為不可重覆讀。

與臟讀的區別:臟讀是讀取到了未提交的數據,而不可重覆讀是讀取到的卻是已經提交的數據,但是違反了資料庫事務一致性的要求。

演示:

image-20230814002516720

事務B插入一條數據並且提交

image-20230814002726465

事務A在此執行select語句,事務A讀取到了事務B提交的數據

image-20230814002910671

一般來說不可重覆讀問題是可以接受的,因為讀取到的是已經提交的數據,本身不會帶來什麼問題。例如Oracle 和 SQL Server的預設的事務隔離級別就是RC。 MySQL預設的事務隔離級別是RR。

在MySQL InnoDB中通過使用 Next-key lock 演算法來避免不可重覆讀問題,並且將不可重覆讀問題定義為幻讀(Phantom problem)

丟失更新

一個數據的更新會被另一個事務的更新操作所覆蓋,從而導致數據的不一致性。

第一種丟失:

A事務撤銷時,把已經提交的B事務的更新數據覆蓋了。這種錯誤可能造成很嚴重的問題,通過下麵的賬戶取款轉賬就可以看出來:

時間 取款事務A 轉賬事務B
T1 開始事務
T2 開始事務
T3 查詢賬戶餘額為1000元
T4 查詢賬戶餘額為1000元
T5 匯入100元把餘額改為1100元
T6 提交事務
T7 取出100元把餘額改為900元
T8 撤銷事務
T9 餘額恢復為1000 元(丟失更新)

第二類丟失更新

A事務覆蓋B事務已經提交的數據,造成B事務所做操作丟失:

時間 轉賬事務A 取款事務B
T1 開始事務
T2 開始事務
T3 查詢賬戶餘額為1000元
T4 查詢賬戶餘額為1000元
T5 取出100元把餘額改為900元
T6 提交事務
T7 匯入100元
T8 提交事務
T9 把餘額改為1100 元(丟失更新)

要避免丟失更新的發生,需要讓事務在這種情況的操作變成串列化,而不是並行操作。即上面的select操作中加上排他鎖。

MySQL鎖的分類:

按照鎖的粒度來說

MySQL主要包含三種類型(級別)的鎖定機制:

全局鎖:鎖的是整個database。

表級鎖:鎖的是某個table。 (表排他鎖,表共用鎖,元數據鎖,自增鎖)

行級鎖:鎖的是某行數據,也可能鎖定行之間的間隙。由某些存儲引擎實現,比如InnoDB。

InnoDB的行級鎖,按照鎖定範圍來說

分為四種:

1.記錄鎖(Record Locks):鎖定索引中一條記錄。

2.間隙鎖(Gap Locks):要麼鎖住索引記錄中間的值,要麼鎖住第一個索引記錄前面的值或者最後一個索

引記錄後面的值。

3.臨鍵鎖(Next-Key Locks):是索引記錄上的記錄鎖和在索引記錄之前的間隙鎖的組合(間隙鎖+記錄

鎖)。

4.插入意向鎖(Insert Intention Locks):做insert操作時添加的對記錄id的鎖。

InnoDB的行級鎖,按照功能來說

分為兩種:

1.共用鎖(S):允許一個事務去讀一行,阻止其他事務獲得相同數據集的排他鎖。

2.排他鎖(X):允許獲得排他鎖的事務更新數據,阻止其他事務取得相同數據集的共用讀鎖和排他寫鎖。

InnoDB行鎖是通過給索引上的索引項加鎖來實現的,因此InnoDB這種行鎖實現特點意味著:只有通過

索引條件檢索的數據,InnoDB才使用行級鎖,否則,InnoDB將使用表鎖!

註意:插入意向鎖

(1)插入意向鎖是一種Gap鎖,不是意向鎖,在insert操作時產生。

(2)在多事務同時寫入不同數據至同一索引間隙的時候,並不需要等待其他事務完成,不會發生鎖等 待。

(3)假設有一個記錄索引包含鍵值4和7,不同的事務分別插入5和6,每個事務都會產生一個加在4-7之 間的插入意向鎖,獲取在插入行上的排它鎖,但是不會被互相鎖住,因為數據行並不衝突。

(4)插入意向鎖不會阻止任何鎖,對於插入的記錄會持有一個記錄鎖。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在本篇文章中,會先介紹 Python 中對象的基礎概念,之後會提到對象的深淺拷貝以及區別。在閱讀後,應該掌握如下的內容: - 理解變數、引用和對象的關係 - 理解 Python 對象中 identity,type 和 value 的概念 - 什麼是 mutable 和 immutable 對象?以及 ...
  • # 《Rust編程之道》學習筆記一 ## 序 ### Rust語言的主要特點 - 系統級語言 - 無GC - 基於LLVM - 記憶體安全 - 強類型+靜態類型 - 混合編程範式 - 零成本抽象 - 線程安全 ### 程式員的快樂 何謂快樂?真正的快樂不僅僅是寫代碼時的“酸爽”,更應該是代碼部署到生產 ...
  • 項目工程中,集成資料庫實現對數據的增曬改查管理,是最基礎的能力,通常涉及三個基礎組件:連接池,持久層框架,數據源。 ...
  • 當我們需要處理一個大量的數據集合時,一次性將其全部讀入記憶體並處理可能會導致記憶體溢出。此時,我們可以採用迭代器`Iterator`和生成器`Generator`的方法,逐個地處理數據,從而避免記憶體溢出的問題。迭代器是一個可以逐個訪問元素的對象,它實現了`python`的迭代協議,即實現了`__iter... ...
  • 通過編碼實戰瞭解quarkus攔截器的另一個高級特性:禁用類級別攔截器,這樣可以避免類級別和方法級別攔截器的疊加衝突 ...
  • [toc] ### 1.晶元手冊中的LED電路圖 ![圖1](https://img-blog.csdnimg.cn/34c2a95aa89c4cbe8a7904429d889564.png) ### 2.官網手冊 ![圖2](https://img-blog.csdnimg.cn/e9b1131d ...
  • 設計字元設備 文件系統調用系統IO的內核處理過程 在Linux文件系統管理中,當應用程式調用open函數時,內核會根據文件路徑找到文件的索引結點(inode),為文件分配文件描述符和文件對象,並根據打開模式和許可權等參數進行相應的操作和設置。 硬體層原理 思路:把底層寄存器配置操作放在文件操作介面里, ...
  • 前面講了Centos如何安裝telnet遠程,這次分享Ubuntu系統如何安裝遠程telnet,作為咱們運維備用遠程途徑 一、下載和安裝 查看系統版本:Ubuntu 22.04.1 LTS 線上安裝: apt install telnet telnetd openbsd-inetd 離線安裝: 離線 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...