目錄
前言
一、表級鎖定&行級鎖定
二、排它鎖&共享鎖
1. 測試不同交易之間排它鎖和共享鎖的兼容性
三、串列化隔離等級測試
首頁 資料庫 mysql教程 MySQL的表級鎖,行級鎖,排它鎖和共用鎖是什麼

MySQL的表級鎖,行級鎖,排它鎖和共用鎖是什麼

Jun 03, 2023 am 10:43 AM
mysql

    前言

    由於我們的業務比較複雜,一個組成事務的相關多個SQL語句是必要的。因此,先解釋什麼是事務。一個事務是指一組SQL語句一起執行,必須要麼全部執行成功,要麼全部執行失敗,不允許存在部分成功或部分失敗的情況。一個事務有ACID特性:

    • 原子性:要嘛全部成功,要嘛全部失敗,這樣才能保證交易的一致性;

    • #一致性:例如銀行的轉賬,扣除一個人的錢肯定要給另一個人加錢,不能光扣除不加,這樣業務就存在問題,數據的一致性就破壞了;

    • 持久性:當我們資料commit以後,資料是先寫到快取當中,快取中的資料還是要慢慢花時間往磁碟上寫,如果此時停電了、宕機或重啟了,我們有redo log重做日誌來保證資料庫的持久性;

    • 隔離性:這塊可以說下事務為什麼要有隔離性,因為事務要允許並發執行,一個業務涉及了很多事務,而我們後台往往有很多業務,要能夠讓他們並發執行,如果所有的事務都是串行執行的話,那這樣我們寫多執行緒程式只有一個執行緒來做事情,這樣效率很低。所以事務要並發執行,但是並發執行涉及了一些問題:事務的安全性&一致性並發的效率問題,我們以這兩個東西為參考點,才得到了MySQL不同等級的同時/隔離,如果交易並發執行時我們完全不隔離的話,就可能會出現臟讀(事務B讀到了事務A還未提交的資料然後,然後用事務A未提交的數據去做計算,得到了很多其他的結果,然後事務A又把那個數據rollback掉,那麼事務B計算出來的都是有問題的數據,髒讀一定會出現問題)、不可重複讀取(以同樣的條件去一個數據,然後再次去查詢的時候發現數據的值有所改變,當然不可重複讀也不一定會有問題,有些業務場景下是允許的,這和業務上資料的安全性和一致性是否嚴格有關)和幻讀(在事務中按照同樣的條件前後兩次查詢的結果資料量不同)這些問題。

    那麼我們為了解決交易並發執行遇到的問題就給了交易的隔離等級:

    • #串行化,串行化完全用鎖來實現,透過鎖給所有事務排序,按順序執行,這樣做數據的安全性高但並發的效率很低,一般我們不會這樣做的。

    • 未提交讀取,對於我們寫的多執行緒程式來說,對於臨界區程式碼片段沒有做任何的並發控制,雖然並發性高但資料安全性很低,未提交讀取還允許髒讀的存在,這是有問題的所以絕對不會使用未提交讀取。 串行化和未提交讀在實際專案中是不會用到的,一般資料庫引擎預設工作在已提交讀取和可重複讀,這兩個隔離級別就結合了資料的安全性&一致性和資料的並發效率,這兩個是由MVCC多版本並發控制機制實現的

    • 已提交讀取,oracle預設工作等級。不允許讀取未commit的數據,這個等級仍然允許不可重複讀取和虛讀產生。

    • 可重複讀取,MySQL預設工作等級。保證事務再次讀取是依然得到相同的數據,部分解決了虛讀,但虛讀是仍然會出現的

    MySQL的表級鎖,行級鎖,排它鎖和共用鎖是什麼

    MySQL的表級鎖,行級鎖,排它鎖和共用鎖是什麼

    注意:

    • 交易隔離等級越高,為避免衝突所花費的效能也就越多,也就是效率低。

    • 在「可重複讀」級別,實際上可以解決部分的虛讀問題,但是不能防止update更新產生的虛讀問題,要禁止虛讀產生,還是需要設置串行化隔離等級。

    交易隔離等級的實作原理:鎖定 MVCC。串行化底層實現原理是鎖,鎖有共享鎖、排它鎖、意向共享鎖、意向排它鎖、間隙鎖和死鎖,InnoDB的已提交讀和可重複讀的底層實現原理:MVCC(多版本並發控制),MVCC提供了一種並發讀取方式,包括快照讀取(同一份資料會有多個版本)、目前讀取、undo log和redo log。 MVCC是已提交讀取和可重複讀取的原理,鎖定是串行化的原理

    MySQL的表級鎖,行級鎖,排它鎖和共用鎖是什麼

    交易日誌被用來實現ACID特性,而共用鎖定、排它鎖定和MVCC則被用來實現一致性(I)特性。交易日誌分為undo log(回滾日誌) 和redo log(重做日誌)

    一、表級鎖定&行級鎖定

    • 級鎖:整張表加鎖。開銷小(因為不用去找表的某一行的記錄加鎖,要修改這張表,直接申請加這張表的鎖),加鎖快,不會出

    • 現死鎖定;鎖定粒度大,發生鎖定衝突的機率高,並發度低

    • 行級鎖定:對某行記錄加鎖。開銷大(需要找到表中對應的記錄,有搜表搜尋引的過程),加鎖慢,會出現死鎖;鎖定粒度最小,發生鎖衝突的機率最低,並發度高

    MySQL的表級鎖,行級鎖,排它鎖和共用鎖是什麼

    MyISAM儲存引擎只支援表格級鎖定,InnoDB支援交易處理,支援行級鎖定,並發能力更好

    MySQL的表級鎖,行級鎖,排它鎖和共用鎖是什麼

    二、排它鎖&共享鎖

    • 排它鎖:又稱為X鎖,寫鎖

    • #共享鎖定:又稱為S鎖,讀鎖

    讀讀(SS)之間是可以相容的,但是讀寫(SX、SX )之間,寫寫(XX)之間是互斥的

    MySQL的表級鎖,行級鎖,排它鎖和共用鎖是什麼

    1. 測試不同交易之間排它鎖和共享鎖的兼容性

    #我們先查看表格SQL及內容

    MySQL的表級鎖,行級鎖,排它鎖和共用鎖是什麼

    檢視隔離等級:

    MySQL的表級鎖,行級鎖,排它鎖和共用鎖是什麼

    #先開啟一個交易A,給id=7的資料加上排它鎖定:

    MySQL的表級鎖,行級鎖,排它鎖和共用鎖是什麼

    #在另一個客戶端開啟交易B:

    MySQL的表級鎖,行級鎖,排它鎖和共用鎖是什麼

    MySQL的表級鎖,行級鎖,排它鎖和共用鎖是什麼

    給id=7不管加排它鎖定和共用鎖定都阻塞了並沒有查詢出來,因為A事務給id=7這一行的資料加了排它鎖,就是寫鎖,其他人不能讀也不能寫。

    總結:不同交易之間對於資料的鎖,只有SS鎖定可以共存,XX、SX、XS都不能共存

    2. 測試行鎖加在索引項目上

    其實行鎖定是加在索引樹上的。

    MySQL的表級鎖,行級鎖,排它鎖和共用鎖是什麼

    每次做完測試都把剛做的rollback。

    用表格的無索引欄位作為過濾條件MySQL的表級鎖,行級鎖,排它鎖和共用鎖是什麼

    那現在事務2取得不同行chenwei的記錄MySQL的表級鎖,行級鎖,排它鎖和共用鎖是什麼

    InnoDB是支援行鎖的,剛才以主鍵id為過濾條件時,事務1和事務2取得不同行的鎖定是可以成功的。然而現在我們發現取得name為chenwei的排它鎖也取得不到了,這是為什麼?讓我們解釋一下:

    InnoDB的行鎖是透過將索引項加鎖來實現的,而不是給表的行記錄加鎖實現的

    而我們用name作為篩選條件沒有用到索引,自然就不會使用行鎖,而是使用表鎖。這就意味著只有透過索引檢索數據,InnoDB才使用行級鎖,否則InnoDB都會使用表鎖!!!

    我們給name欄位加上索引:

    MySQL的表級鎖,行級鎖,排它鎖和共用鎖是什麼

    然後再做剛才的動作:

    MySQL的表級鎖,行級鎖,排它鎖和共用鎖是什麼

    #######

    我們發現,為name加上索引後,兩個交易可以取得到不同行的排它鎖定(for update),再一次證明了InnoDB的行鎖定是加在索引項目上的。

    MySQL的表級鎖,行級鎖,排它鎖和共用鎖是什麼

    因為現在name走的是索引, 透過zhangsan在輔助索引樹上找到它所在行記錄的id是7,然後到主鍵索引樹上,取得對應行記錄的排他鎖定(個人猜測應該是輔助索引樹和主鍵索引樹對應的記錄都加了鎖)

    三、串列化隔離等級測試

    串行化所有交易用的都是共享鎖或排它鎖,不需要用手動添加。 select取得的是共享鎖,insert、delete和update取得的都是排它鎖。

    設定串列化隔離等級:

    MySQL的表級鎖,行級鎖,排它鎖和共用鎖是什麼

    #兩個交易可以同時取得共享鎖定(SS共存:

    MySQL的表級鎖,行級鎖,排它鎖和共用鎖是什麼

    現在讓交易2插入資料;

    MySQL的表級鎖,行級鎖,排它鎖和共用鎖是什麼

    #由於Insert需要加排它鎖,但是由於事務1已經對整張表加了共享鎖,因此事務2無法再對錶成功加鎖(sx不共存)

    rollback一下,把所有獲取鎖的狀態都回退掉:

    MySQL的表級鎖,行級鎖,排它鎖和共用鎖是什麼

    開啟兩個交易:

    MySQL的表級鎖,行級鎖,排它鎖和共用鎖是什麼

    ##因為我們給name加上了索引,以上的select相當於為name為zhangsan的資料加上了行共享鎖定

    交易2update;

    MySQL的表級鎖,行級鎖,排它鎖和共用鎖是什麼

    事務2不能update,因為此時已經被事務1的共享鎖定鎖住了整個表

    事務2在輔助索引樹上找zhangsan,找到對應的主鍵值,然後去主鍵索引樹找到對應的記錄,但是發現這行記錄已經被共享鎖鎖住了,事務2可以獲取共享鎖,但是不能獲取排他鎖

    MySQL的表級鎖,行級鎖,排它鎖和共用鎖是什麼##我們再用主鍵索引試試id能不能update

    MySQL的表級鎖,行級鎖,排它鎖和共用鎖是什麼依然阻塞住了,雖然我們where後面的欄位現在使用的id而不是name,但是name也是透過輔助索引樹找到對應的主鍵,再到主鍵索引樹上找相應的記錄,而主鍵索引樹上的記錄加了鎖

    我們update id=8的數據,成功了。因為我們select的時候,只是給id=7的資料加上了行鎖,我們操作id=8的資料當然可以成功

    MySQL的表級鎖,行級鎖,排它鎖和共用鎖是什麼

    #有索引,則使用行鎖;沒有索引,則使用表鎖。

    表級鎖還是行級鎖說的是鎖的粒度,共享鎖和排他鎖說的是鎖的性質,不管是表鎖還是行鎖,都有共享鎖和排他鎖的區分。

    串行化玩的就是排它鎖和共享鎖,在可重複讀取級別下,不手動加鎖的話,用的就是MVCC機制,實際上並沒有用到鎖,我們也可以手動加鎖。InnoDB如果不建立索引的話,用的是表鎖,如果查詢的時候用到了索引項,它用的就是行鎖了,行鎖是將索引加鎖,而不是單純地為一行資料加鎖。

    以上是MySQL的表級鎖,行級鎖,排它鎖和共用鎖是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

    本網站聲明
    本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

    熱AI工具

    Undresser.AI Undress

    Undresser.AI Undress

    人工智慧驅動的應用程序,用於創建逼真的裸體照片

    AI Clothes Remover

    AI Clothes Remover

    用於從照片中去除衣服的線上人工智慧工具。

    Undress AI Tool

    Undress AI Tool

    免費脫衣圖片

    Clothoff.io

    Clothoff.io

    AI脫衣器

    Video Face Swap

    Video Face Swap

    使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

    熱門文章

    <🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
    3 週前 By 尊渡假赌尊渡假赌尊渡假赌
    北端:融合系統,解釋
    3 週前 By 尊渡假赌尊渡假赌尊渡假赌
    Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
    3 週前 By 尊渡假赌尊渡假赌尊渡假赌

    熱工具

    記事本++7.3.1

    記事本++7.3.1

    好用且免費的程式碼編輯器

    SublimeText3漢化版

    SublimeText3漢化版

    中文版,非常好用

    禪工作室 13.0.1

    禪工作室 13.0.1

    強大的PHP整合開發環境

    Dreamweaver CS6

    Dreamweaver CS6

    視覺化網頁開發工具

    SublimeText3 Mac版

    SublimeText3 Mac版

    神級程式碼編輯軟體(SublimeText3)

    熱門話題

    Java教學
    1666
    14
    CakePHP 教程
    1426
    52
    Laravel 教程
    1328
    25
    PHP教程
    1273
    29
    C# 教程
    1253
    24
    laravel入門實例 laravel入門實例 Apr 18, 2025 pm 12:45 PM

    Laravel 是一款 PHP 框架,用於輕鬆構建 Web 應用程序。它提供一系列強大的功能,包括:安裝: 使用 Composer 全局安裝 Laravel CLI,並在項目目錄中創建應用程序。路由: 在 routes/web.php 中定義 URL 和處理函數之間的關係。視圖: 在 resources/views 中創建視圖以呈現應用程序的界面。數據庫集成: 提供與 MySQL 等數據庫的開箱即用集成,並使用遷移來創建和修改表。模型和控制器: 模型表示數據庫實體,控制器處理 HTTP 請求。

    MySQL和PhpMyAdmin:核心功能和功能 MySQL和PhpMyAdmin:核心功能和功能 Apr 22, 2025 am 12:12 AM

    MySQL和phpMyAdmin是強大的數據庫管理工具。 1)MySQL用於創建數據庫和表、執行DML和SQL查詢。 2)phpMyAdmin提供直觀界面進行數據庫管理、表結構管理、數據操作和用戶權限管理。

    MySQL與其他編程語言:一種比較 MySQL與其他編程語言:一種比較 Apr 19, 2025 am 12:22 AM

    MySQL与其他编程语言相比,主要用于存储和管理数据,而其他语言如Python、Java、C 则用于逻辑处理和应用开发。MySQL以其高性能、可扩展性和跨平台支持著称,适合数据管理需求,而其他语言在各自领域如数据分析、企业应用和系统编程中各有优势。

    解決數據庫連接問題:使用minii/db庫的實際案例 解決數據庫連接問題:使用minii/db庫的實際案例 Apr 18, 2025 am 07:09 AM

    在開發一個小型應用時,我遇到了一個棘手的問題:需要快速集成一個輕量級的數據庫操作庫。嘗試了多個庫後,我發現它們要么功能過多,要么兼容性不佳。最終,我找到了minii/db,這是一個基於Yii2的簡化版本,完美地解決了我的問題。

    laravel框架安裝方法 laravel框架安裝方法 Apr 18, 2025 pm 12:54 PM

    文章摘要:本文提供了詳細分步說明,指導讀者如何輕鬆安裝 Laravel 框架。 Laravel 是一個功能強大的 PHP 框架,它 упростил 和加快了 web 應用程序的開發過程。本教程涵蓋了從系統要求到配置數據庫和設置路由等各個方面的安裝過程。通過遵循這些步驟,讀者可以快速高效地為他們的 Laravel 項目打下堅實的基礎。

    解決MySQL模式問題:TheliaMySQLModesChecker模塊的使用體驗 解決MySQL模式問題:TheliaMySQLModesChecker模塊的使用體驗 Apr 18, 2025 am 08:42 AM

    在使用Thelia開發電商網站時,我遇到了一個棘手的問題:MySQL模式設置不當,導致某些功能無法正常運行。經過一番探索,我找到了一個名為TheliaMySQLModesChecker的模塊,它能夠自動修復Thelia所需的MySQL模式,徹底解決了我的困擾。

    在MySQL中解釋外鍵的目的。 在MySQL中解釋外鍵的目的。 Apr 25, 2025 am 12:17 AM

    在MySQL中,外鍵的作用是建立表與表之間的關係,確保數據的一致性和完整性。外鍵通過引用完整性檢查和級聯操作維護數據的有效性,使用時需注意性能優化和避免常見錯誤。

    比較和對比Mysql和Mariadb。 比較和對比Mysql和Mariadb。 Apr 26, 2025 am 12:08 AM

    MySQL和MariaDB的主要區別在於性能、功能和許可證:1.MySQL由Oracle開發,MariaDB是其分支。 2.MariaDB在高負載環境中性能可能更好。 3.MariaDB提供了更多的存儲引擎和功能。 4.MySQL採用雙重許可證,MariaDB完全開源。選擇時應考慮現有基礎設施、性能需求、功能需求和許可證成本。

    See all articles