MySQL鎖(樂觀鎖、悲觀鎖、多粒度鎖)

来源:https://www.cnblogs.com/duizhangz/archive/2022/06/06/16347128.html
-Advertisement-
Play Games

鎖 併發事務可能出現的情況: 讀-讀事務併發:此時是沒有問題的,讀操作不會對記錄又任何影響。 寫-寫事務併發:併發事務相繼對相同的記錄做出改動,因為寫-寫併發可能會產生臟寫的情況,但是沒有一個隔離級別允許臟寫的情況發生。MySQL使用鎖的機制來控制併發情況下讓事務對一條記錄進行排隊修改,只有對記錄修 ...


併發事務可能出現的情況:

  • 讀-讀事務併發:此時是沒有問題的,讀操作不會對記錄又任何影響。

  • 寫-寫事務併發:併發事務相繼對相同的記錄做出改動,因為寫-寫併發可能會產生臟寫的情況,但是沒有一個隔離級別允許臟寫的情況發生。MySQL使用鎖的機制來控制併發情況下讓事務對一條記錄進行排隊修改,只有對記錄修改的事務提交了才能讓下一個事務對記錄進行修改。

    當第一個事務嘗試對一條記錄進行修改。會和記錄行關聯一個鎖結構。

image

trx信息: 代表鎖結構是哪個事務產生的。

is_waiting:false代表擁有記錄的修改權,true表示等待鎖資源釋放。

​ 當第二個事務嘗試獲得鎖,失敗也會創建一個鎖結構將is_waiting置為true,並填入事務信息,加入記錄的鎖結構中。

image

​ 當第一個事務提交結束釋放鎖資源,並會喚醒下一個事務將其等待狀態設置為false,讓其其獲得鎖資源。

image

  • 讀-寫事務併發:有兩種解決方案
    • MVCC(多版本併發控制) + 加鎖。即上文我們說過MVCC只能用作查詢數據,所以我們使用MVCC來解決併發下事務對記錄修改同時的讀取不出現臟讀、不可重覆讀和幻讀。寫操作就是用加鎖的方式來進行控制。
    • 讀、寫都使用加鎖。這樣子讀寫的話,讀和寫都要進行加鎖,相當於讀和寫操作之間要像寫和寫一樣進行排隊。

一致性讀

事務利用MVCC進行讀取操作可以被稱為一致性讀、一致性無鎖讀又或者快照讀。一致性讀不會產生加鎖操作。MVCC我們之前文章都講過

鎖定讀

就是我們讀寫都是用加鎖的操作。

學習Java的JUC的時候,對於讀寫鎖就是差不多的。

  • 共用鎖 Shared Locks,簡稱S鎖。要讀取一條記錄時,需要先獲取S鎖
  • 獨占鎖 Exclusive Locks,簡稱X鎖。當我們需要更改一條記錄時,需要獲取記錄的X鎖。

S鎖是可以共用的,即多個事務之間共同獲取S鎖。但是X鎖只能被一個事務擁有,直到事務提交然後才能釋放。

不同寫操作加鎖過程

  • delete,會先獲取記錄的X鎖,然後delete_mark 為1,然後提交事務釋放鎖,放入垃圾鏈表就OK。
  • update
    • 如果沒更新主鍵,且更新後數據行各列的大小不發生改變,就直接獲取X鎖,然後更新數據即可。
    • 如果沒更新主鍵,且更新後數據行各列的大小發生改變,先獲取記錄的X鎖,然後將其徹底刪除,然後插入更新的記錄,新插入的記錄由隱式鎖進行保護。
    • 如果更新了主鍵,就直接先獲取X鎖,然後先delete的流程來一下,然後insert的流程來一下,都是加的X鎖。
  • insert,直接插入新數據,由隱式鎖來保證併發事務安全。

多粒度鎖

上面說的都是行鎖,粒度較細,我們還可以加一個粒度較大的鎖,表級鎖。

  • 共用鎖,簡稱S鎖,對錶加S鎖,其他事務可以繼續對錶或者行加S鎖。但是如果想對錶加X鎖,或者表內的行加X鎖,就需要進行排隊等待表的S鎖釋放。
  • 獨占鎖,簡稱X鎖,對錶加X鎖,其他事務就不能對錶或者行加S鎖或X鎖了,只能排隊。

但是會出現一種情況,就是表內行加了行級鎖,但是我們想對錶加表級鎖,我們怎麼才能知道表內有行級鎖呢?不能一條一條遍歷吧。

  • 意向共用鎖,簡稱IS鎖,當有事務需要對一條行記錄加S鎖時,先對錶加一個IS鎖。
  • 意向獨占鎖,簡稱IX鎖,當有事務需要對一條行記錄加X鎖時,先對錶加一個IX鎖。

IS鎖和IX鎖的作用就是為了讓我們快速知道,表內行記錄中是否有加了鎖,是否能加表級鎖。

Innodb中的鎖

表級鎖

  • S鎖,X鎖
  • IS鎖,IX鎖
  • AUTO_INC鎖,這個鎖是用在自增欄位的自增當中的。
    • 如果我們不能確定插入的數量,即當我們使用insert ... select 、replace ... select、load data等語句,我們無法確定插入的條數是多少,innodb會使用AUTO_INC鎖。這個鎖是會在表的層面進行加鎖,然後會對插入的每條記錄進行分配一個自增值。
    • 如果我們是能夠確定的插入數量,比如insert into x(a) values('ss'),('dd');我們可以確定插入的記錄是兩條。innodb就會採用一個輕量級鎖,在為插入語句分配好這個自增列的值後,就會將其釋放。

在innodb中維護了一個系統變數innodb_autoinc_lock_mode的變數。

當值為0時就是直接採用AUTO_INC鎖,不管確不確定。

當值為1時就是採用兩種混合的方式,也就是上述的方式。

當值為2時就是一律採用輕量級鎖的方式,可能會造成不同事務的自增列產生的值是交叉的,在主從中是不安全的。不是很理解,沒有弄過主從。

行級鎖

  • Record Locks:當我們要對某個數據行進行操作,我們就會向數據行中加入這個鎖。官方命名:LOCK_REC_NOT_GAP。分為S鎖和X鎖這種類型的鎖。解決了併發事務之間對一條記錄的讀取和修改。可以解決臟寫、臟讀、不可重覆讀。

  • Gap Locks:但是出現幻讀怎麼解決呢?Gap鎖就是為瞭解決幻讀。Gap鎖能夠防止當前記錄和前一個記錄之間的間隙不能插入新數據。當新數據發現下一條數據有gap鎖,就不會執行插入。

    我們要讓查詢的區間不要讓其他事務進行插入數據,以防止出現幻讀的情況。就會在第一次查詢的時候,比如我們查詢記錄(2,8)就會在8號記錄加一個gap鎖,這樣如果我們插入4號記錄就無法插入。如果我們要控制(2,+∞),就會在數據頁的Supremun的數據行加入gap鎖。

  • key-next Locks:就是Record和Gap鎖的合體,就能控制當前行,並且當前行和前一條的數據行之間的間隙不能插入新數據。

  • Insert Intention Locks: 可以叫做插入意向鎖,就是當前如果記錄的下一條有gap或key-next鎖,就不能插入,此時就會在記憶體中生成一個鎖結構,表示某個間隙想要插入新紀錄,正在等待,保存在下一條的數據行中。

image

插入意向鎖就是JUC的一個非公平的AQS啊,就是他不會阻止別的事務繼續獲得數據行的其他鎖,就是這個插入意向鎖可能會一直一直等下去。

  • 隱式鎖。即我們上面講的,在事務進行插入的時候如果有gap鎖就會加個插入意向鎖事務進入等待狀態,但是如果沒有的話,我們就會直接進行插入。導致的結果就是什麼,我們插入的數據沒有進行加鎖保護,這時其他事務的可以直接select或者更新,直接導致臟讀,或者臟寫。

    幻讀已經被Gap鎖解決了所以不會出現哈,這裡是在可以插入的時候可能出現的錯誤,因為如果有Gap說明別的事務可能會讀取數據,不能插入,只有提交了Gap鎖取消了才能進行插入,隱式鎖是在這時候發揮作用。

    所以在數據行插入到頁中時,會判斷插入數據行的事務的trx_id是否還是活躍的狀態,如果還是活躍事務,就會為當前插入的數據行創建一個X鎖。如果不活躍了,表示事務已經提交就可以放心去改和去查了。

    在聚簇索引中就是這個流程,但是在二級索引中數據行沒有維護一個trx_id,我們就需要判斷二級索引中維護的PAGE_MAX_TRX_ID即最大修改二級索引的事務號,如果小於最小活躍事務ID,就可以放心改了,否則需要回表然後進行一遍聚簇索引的流程。???


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

-Advertisement-
Play Games
更多相關文章
  • 鏡像下載、功能變數名稱解析、時間同步請點擊 阿裡雲開源鏡像站 前言 沒安裝vm的小伙伴們,可來這~VM安裝和配置 可選擇優質模板,享受閱讀 VM設置 下載centso鏡像 阿裡雲:下載 安裝VM 有什麼要註意嗎?沒有,除了存儲路徑外,其他都可以自己下一步直到完成,所以可以直接跳到在這兒,不必浪費寶貴時間,廢 ...
  • 一、函數概述 • PL/SQL中的過程和函數(通常稱為子程式)是PL/SQL塊的一種特殊的類型,這種類型的子程式可以以編譯的形式存放在資料庫中,併為後續的程式塊調用。 • 相同點:完成特定功能的程式 • 不同點:是否用return語句返回值 二、函數語法 CREATE [OR REPLACE] FU ...
  • mysql精簡單機版,免登錄,可複製,不啟動服務,與本機mysql無衝突 ...
  • datebase管理 1.創建資料庫-create 語法:create database 資料庫名 character set 編碼 # 註意:預設會存在四個資料庫,其資料庫中存儲的是mysql資料庫伺服器的配置的數據 示例:create database firstDB character set ...
  • 搭建從庫,本質上需要的只是一個一致性備份集及這個備份集對應的位置點信息。之前介紹的幾個備份工具( MySQL中如何選擇合適的備份策略和備份工具 )均可滿足。 這裡,我們重點看看如何基於 XtraBackup 搭建從庫。 整個過程其實比較簡單,無非是備份還原。唯一需要註意的是建立複製時位置點的選擇,包 ...
  • 隨著表中記錄(數據行)的不斷積累,存儲數據逐漸增加,有時我們可能希望計算出這些數據的合計值或者平均值等。 本文介紹如何使用 SQL 語句對錶進行聚合和分組的方法。此外,還介紹在彙總操作時指定條件,以及對彙總結果進行升序、降序的排序方法。 一、對錶進行聚合查詢 本節重點 使用聚合函數對錶中的列進行計算 ...
  • 對實時數據湖的解讀 數據湖的概念是比較寬泛的,不同的人可能有著不同的解讀。這個名詞誕生以來,在不同的階段被賦予了不同的含義。 數據湖的概念最早是在 Hadoop World 大會上提出的。當時的提出者給數據湖賦予了一個非常抽象的含義,他認為它能解決數據集市面臨的一些重要問題。 其中最主要的兩個問題是 ...
  • 來源公眾號:SQL資料庫運維 原文鏈接:https://mp.weixin.qq.com/s?__biz=MzI1NTQyNzg3MQ==&mid=2247485400&idx=1&sn=432b580ed77224bf883db109cb7767b4&chksm=ea3753a8dd40dabed ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...