MySQL涉及鎖的問題

来源:https://www.cnblogs.com/HuiH/archive/2020/03/26/12576983.html
-Advertisement-
Play Games

如何併發的訪問資料庫呢?答案就是加鎖。 接下來說一下,資料庫的鎖機制,資料庫中都有哪些鎖? 首先呢,鎖是一種併發控制技術,鎖是用來在多個用戶同時訪問同一個數據的時候保護數據的。 有2種基本的鎖類型: 共用(S)鎖:多個事務可封鎖一個共用頁;任何事務都不能修改該頁;通常是該頁被讀取完畢,S鎖立即被釋放 ...


如何併發的訪問資料庫呢?答案就是加鎖

接下來說一下,資料庫的鎖機制,資料庫中都有哪些鎖?

  首先呢,鎖是一種併發控制技術,鎖是用來在多個用戶同時訪問同一個數據的時候保護數據的。

有2種基本的鎖類型:

  共用(S)鎖:多個事務可封鎖一個共用頁;任何事務都不能修改該頁;通常是該頁被讀取完畢,S鎖立即被釋放。在執行select語句的時候需要給操作對象(表或一些記錄)加上共用鎖,但加鎖之前需要檢查是否有排他鎖,如果沒有,則可以加共用鎖(一個對象上可以加N個共用鎖),否則不行。共用鎖通常在執行完select語句之後被釋放,當然也可能是在事務結束(包括正常結束和異常結束)的時候被釋放,主要取決與資料庫所設置的事務隔離級別。

  排它(X)鎖:僅允許一個事務封鎖此頁;其他任何事務必須等到X鎖被釋放才能對該頁進行訪問;X鎖一直到事務結束才能被釋放。執行insert、update、delete語句的時候需要給操作的對象加排它鎖,在加排他鎖之前必須確認該對象上沒有其他任何鎖,一旦加上排它鎖之後,就不能再給這個對象加其他任何鎖。排它鎖的釋放通常是在事務結束的時候(當然也有例外,就是在資料庫事務隔離級別被設置為Read Uncommitted(讀未提交數據)的時候,這種情況下排他鎖會在執行完更新操作之後被釋放,而不是在事務結束的時候)。

按鎖的機制

既然使用了鎖,就有出現死鎖的可能。

產生死鎖的四個必要條件:

  互斥條件:一個資源每次只能被一個進程使用。

  請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放。

  不可剝奪條件:進程已獲得的資源,在未使用完之前,不能強行剝奪。

  環路等待條件:若幹個進程之間形成一種頭尾相接的迴圈等待資源關係。

只要系統發生了死鎖,這些條件必然成立,而只要上述條件之一不滿足,就不會發生死鎖。

預防死鎖

預防死鎖的發生只需要破壞死鎖產生的四個必要條件之一即可。

1)破壞互斥條件

  如果允許系統資源都能共用使用,則系統不會進入死鎖狀態。但有些資源根本不能同時訪問,如印表機等臨界資源只能互斥使用。所以破壞互斥條件而預防死鎖的方法不太可行,而且在有些場合應該保護這種互斥性。

2)破壞不可剝奪條件

  當一個已保持了某些不可剝奪資源的進程,請求新的資源而得不到滿足時,它必須釋放已經保持的所有資源,待以後需要時再重新申請。這意味著,一個進程已占有的資源會被暫時釋放,或者說是被剝奪了,或從而破壞了不可剝奪條件。

  該策略實現起來比較複雜,釋放已獲得的資源可能造成前一階段工作的失效,反覆地申請和釋放資源會增加系統開銷,降低系統吞吐量。這種方法常用於狀態易於保存和恢復的資源,如CPU的寄存器及記憶體資源,一般不能用於印表機之類的資源。

3)破壞請求和保持的條件

  採用預先靜態分配方法,即進程在運行前一次申請完它所需要的全部資源,在它的資源為滿足前,不把它投入運行。一旦投入運行後,這些資源就一直歸它所有,也不再提出其他資源請求,這樣就可以保證系統不會發生死鎖。

  這種方式實現簡單,但缺點也顯而易見,系統資源被嚴重浪費,其中有些資源可能僅在運行初期或運行快結束時才使用,甚至根本不使用。而且還會導致“饑餓”現象,當由於個別資源長期被其他進程占用時,將致使等待該資源的進程遲遲不能開始運行。

4)破壞環路等待條件

  為了破壞環路等待條件,可採用順序資源分配法。首先給系統中的資源編號,規定每個進程,必須按編號遞增的順序請求資源,同類資源一次申請完。也就是說,只要進程提出申請分配資源Ri,則該進程在以後的資源申請種,只能申請編號大於Ri的資源。

  這種方法存在的問題時,編號必須相對穩定,這就限制了新類型設備的增加;儘管在為資源編號時已考慮到大多數作業實際使用這些資源的順序,但也經常會發生作業使用資源的順序與系統規定順序不同的情況,造成資源的浪費;此外,這種按規定次序申請資源的方法,也必然會給用戶的編程帶來麻煩。

解除死鎖

  1)從死鎖進程處剝奪資源;

  2)終止部分或全部進程;

MySQL鎖的粒度(即鎖的級別)

MySQL各存儲引擎使用了三種類型(級別)的鎖定機制:行級鎖定、頁級鎖定和表級鎖定。

  1、表級鎖:直接鎖定整張表,在你鎖定期間,其他進程無法對該表進行寫操作。如果你是寫鎖,則其他進程則讀也不允許。特點:開銷小,加鎖快;不會出現死鎖;鎖粒度最大,發生鎖衝突的概率最高,併發度最低。

    MyISAM存儲引擎採用的是表級鎖。

    有兩種模式:表共用讀鎖和表獨占寫鎖。加讀鎖的命令:lock table 表名 read;  去掉鎖的命令:unlock tables。

    支持併發插入:支持查詢和插入操作併發運行(在表尾併發插入)。

    鎖調度機制:寫鎖優先。一個進程請求某個MyISAM表的讀鎖,同時另一個進程也請求同一表的寫鎖,MySQL如何處理呢?答案是寫進程先獲得鎖。

  2、行級鎖:僅對指定的記錄進行加鎖,這樣其他進程還是可以對同一個表中的其他記錄進行操作。特點:開銷大,加鎖慢;會出現死鎖;鎖粒度最小,發生鎖衝突的概率最低,併發度也最高。

    InnoDB存儲引擎既支持行級鎖,也支持表級鎖,但預設情況下是採用行級鎖。

  3、頁級鎖:一次鎖定相鄰的一組記錄。開銷和加鎖時間介於表鎖和行鎖之間;會出現死鎖;鎖定粒度介於表鎖和行鎖治安,併發度一般。

  最常用的處理多用戶併發訪問的方法是加鎖。當一個用戶鎖定資料庫中的某個對象時,其他用戶就不能再訪問該對象。加鎖對併發訪問的影響體現在鎖的粒度上。比如,(表鎖)放在一個表上的鎖限制對整個表的併發訪問;(頁鎖)放在數據頁上的鎖限制了對整個數據頁的訪問;(行鎖)放在行上的鎖只限制對該行的併發訪問。

樂觀鎖和悲觀鎖的概念,實現方式和使用場景

鎖有兩種機制:悲觀鎖和樂觀鎖

  悲觀鎖,鎖如其名,它對世界是悲觀的,它認為別人訪問正在改變的數據的概率是很高的,所以從數據開始更改時就將數據鎖住,直到更改完成才釋放。

一個典型的依賴資料庫的悲觀鎖調用:

  select * from account where name="Erica" for update

  這條SQL語句鎖定了account表中所有符合檢索條件(name="Erica")的記錄。本事務提交之前(事務提交時會釋放事務過程中的鎖),外界無法修改這些記錄。該語句用來鎖定特定的行(如果where子句,就是滿足where條件的那些行)。當這些行被鎖定後,其他會話可以選擇這些行,但不能更改或刪除這些行,直到該語句的事務被commit語句或rollback語句結束終止。需要註意的是,select ...for update要放到MySQL的事務種,即begin和commit中,否則不起作用。

  悲觀所可能會造成加鎖的時間很長,併發行不好,特別是長事務,影響系統的整體性能。

  悲觀所的實現方式:

    悲觀鎖,也是基於資料庫的鎖機制實現。傳統的關係型資料庫裡邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖、寫鎖等,都是在做操作之前先上鎖。

  樂觀鎖,它對世界比較樂觀,認為別人訪問正在改變的數據的概率是很低的,所以直到修改完成準備提交所作的修改到資料庫的時候才會將數據鎖住,當你讀取以及改變該對象時並不加鎖,完成更改後釋放。樂觀鎖不能解決臟讀的問題。

  樂觀鎖加鎖的時間要比悲觀鎖短,大大提升了大併發量下的系統整體性能表現。

  樂觀鎖的實現方式

    1、大多是基於數據版本(version)記錄機制實現,需要為每一行數據增加一個版本標識(也就是每一行數據多一個欄位version),每次更新數據都要更新對應的版本號+1。

    工作原理:讀出數據時,將此版本一同讀出,之後更新時,對此版本號加一。此時,將提交的數據的版本信息與資料庫表對應記錄的當前版本信息進行比對,如果提交的數據版本號大於資料庫表當前版本號,則予以更新,否則認為是過期數據,不得不重新讀取該對象並作出更改。

    2、使用時間戳來實現

    同樣是在需要樂觀鎖控制的table中增加一個欄位,名稱無所謂,欄位類型使用時間戳(timestamp),和上面的version類似,也是在更新提交的時候檢查當前資料庫中數據的時間戳和自己更新前取到的時間戳進行對比,如果一致則OK,否則就是版本衝突。

悲觀鎖與樂觀鎖的適用場景:

  如果併發量不大,可以使用悲觀鎖解決併發問題;但如果系統的併發量非常大的話,悲觀所定會帶來非常大的性能問題,所以我們就要選擇樂觀鎖定的方法。現在大部分應用都應該是樂觀鎖的。


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

-Advertisement-
Play Games
更多相關文章
  • 緩存穿透 緩存穿透是指查詢一個一定不存在的數據,由於緩存是不命中時被動寫的,並且出於容錯考慮,如果從存儲層查不到數據則不寫入緩存,這將導致這個不存在的數據每次請求都要到存儲層去查詢,失去了緩存的意義。在流量大時,可能DB就掛掉了,要是有人利用不存在的key頻繁攻擊我們的應用,這就是漏洞。 解決方案 ...
  • 本文存在 "視頻版本" ,請知悉 項目簡介 項目來源於: "https://gitee.com/PositiveMumu/CakesShop/tree/master" 這次分享一個蛋糕商場系統,還是很簡單的系統。界面簡潔但不粗糙。。 本系統基於 JSP+Servlet+C3P0+Mysql+JDBC ...
  • truncate 與 delete 的區別 truncate table :刪除內容、不刪除定義、釋放空間。 delete table : 刪除內容、不刪除定義、不釋放空間。 drop table :刪除內容和定義,釋放空間。 1、truncate table 表名,只能刪除表中全部數據。 dele ...
  • 在瞭解臟讀,不可重覆度,幻讀之前,首先要明白這三種情況的出現都是和資料庫併發事務有關聯的,如果所有的讀寫都按照隊列的形式進行,就不會出現問題。 名詞解析和解決方案 臟讀 臟讀又稱無效數據讀出(讀出了臟數據)。一個事務讀取另外一個事務還沒有提交的數據叫臟讀。 例如:事務T1修改了某個表中的一行數據,但 ...
  • `Redis key value`存儲系統。 Redis支持五種數據類型: (字元串) (列表) (hash表) (集合) (有序集合) 和 類似, 支持的數據類型更豐富、數據能持久化。 把數據全部存儲在記憶體中,斷電後會掛掉,數據不能超過記憶體大小。 而redis`數據會定期備份到硬碟上。 落地策略 ...
  • 1.在 資料庫內如何讓自動增加欄位從0開始 2.表中有A B C三列時,用SQL語句實現:當A列大於B列時選擇A列,否則選擇B列,當B列大於C列時選擇B,否則選擇C列 3. 是一個 存儲系統。支持五種數據類型: (1) (字元串) (2) (列表) (3) (`hash`表) (4) (集合) (5 ...
  • 很苦惱,PROD上的SSIS項目,日積月累的往裡部署,加包,也沒覺得是個什麼問題。 但是今天從需要從PROD上把這個項目中所有的包都down下來,VS居然報錯Out Of Memory,無論是直接連接SSIS Catelog或者用SSMS導出ispac均報錯。 解決方法很簡單,使用PowerShel ...
  • 2020 年 3 月,Kylin 社區決定將 Kylin 的標語從「Extreme OLAP Engine for Big Data」更改為 「Analytical Data Warehouse for Big Data」,以更加準確地描述 Kylin 的能力和定位,也更容易地讓用戶通過搜索引擎檢索... ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...