目錄
一、交易隔離機制的選擇
二、表格級鎖定&行級鎖定
三、排它鎖定(Exclusive)和共用鎖定(Shared)
1. 測試不同交易之間排它鎖和共享鎖的相容性
首頁 資料庫 mysql教程 MySQL表鎖、行鎖、排它鎖及共用鎖怎麼使用

MySQL表鎖、行鎖、排它鎖及共用鎖怎麼使用

Jun 03, 2023 am 10:49 AM
mysql

    一、交易隔離機制的選擇

    • #如果我們完全不管,使用未提交讀取的事務隔離機制,任由這些執行緒並發操作資料庫,那就會出現髒讀(讀取了未commit的資料)、不可重複讀取(兩次查詢值不同)、幻讀(兩次查詢資料量不同)等問題,資料的安全性最低,優點是並發效率非常高,一般不會使用

    • 如果我們序列化(靠鎖定實現),透過鎖定給所有的事務都排序,雖然資料的安全性提高了,並發的效率就太低了,一般也不會使用

    • 所以我們一般用的是已提交讀取、可重複讀這兩個隔離級別,平衡了資料的安全性,一致性以及並發的效率,是由MVCC多版本並發控制實現的(MVCC是已提交讀取和可重複讀取的原理,鎖定是串行化的原理)

    二、表格級鎖定&行級鎖定

    #表級鎖:整張表加鎖。開銷小(因為不用去找表的某一行的記錄進行加鎖,要修改這張表,直接申請加這張表的鎖),加鎖快,不會出現死鎖;鎖粒度大,發生鎖衝突的機率高,並發度低

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

    MySQL表鎖、行鎖、排它鎖及共用鎖怎麼使用

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

    1. InnoDB行鎖是透過給索引上的索引項目加鎖來實現的,而不是給表的行記錄加鎖實現的,這就意味者只有通過索引條件檢索數據,InnoDB才使用行級鎖,否則InnoDB將使用表鎖

    2. 由於InnoDB的行鎖實作是針對索引欄位新增的鎖,不是針對行記錄加的鎖,因此雖然存取的是InnoDB引擎下表的不同行,但如果使用相同的索引字段作為過濾條件,仍然會發生鎖定衝突,只能串行進行,不能並發進行

    3. 即使SQL中使用了索引,但是經過MySQL的優化器後,如果認為全表掃描比使用索引效率高,此時會放棄使用索引,因此也不會
      使用行鎖,而是使用表鎖,例如對一些很小的表,MySQL就不會去使用索引

    三、排它鎖定(Exclusive)和共用鎖定(Shared)

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

    • 共享鎖,又稱為S鎖,讀鎖

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

    對事務加X和S鎖之間有以下的關係:

    • 一個事務對資料物件A加了S 鎖,可以對A進行讀取操作但不能進行update操作,加鎖期間其它事務能對A加S鎖但不能加X 鎖

    • 一個事務對資料物件A加了X 鎖,就可以對A進行讀取和更新,加鎖期間其它事務不能對A加任何鎖

    顯示加鎖:select … lock in share mode強制取得共享鎖,select … for update取得排它鎖

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

    我們先查看表格的SQL以及內容

    MySQL表鎖、行鎖、排它鎖及共用鎖怎麼使用

    看隔離等級:

    MySQL表鎖、行鎖、排它鎖及共用鎖怎麼使用

    MySQL表鎖、行鎖、排它鎖及共用鎖怎麼使用

    MySQL表鎖、行鎖、排它鎖及共用鎖怎麼使用##首先開啟一個事務,給id=7的資料加上排它鎖定

    MySQL表鎖、行鎖、排它鎖及共用鎖怎麼使用在用另一個客戶端開啟事務

    我們用另一個事務的服務執行緒為id=7的資料加上排它鎖,阻塞了

    我們嘗試給id=7的資料加上共享鎖,還是阻塞了

    總結:不同事務之間對於資料的鎖,只有SS鎖可以共存,XX、SX、XS都不能共存######2. 測試行鎖加在索引項目上############其實行鎖定是加在索引樹上的#######

    MySQL表鎖、行鎖、排它鎖及共用鎖怎麼使用

    用表格的無索引欄位作為過濾條件

    MySQL表鎖、行鎖、排它鎖及共用鎖怎麼使用

    #交易2現在同樣想取得這條記錄的排它鎖,可想而知地失敗了;那現在事務2取得chenwei的記錄的排它鎖,試試能不能成功

    MySQL表鎖、行鎖、排它鎖及共用鎖怎麼使用

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

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

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

    我們給name欄位加上索引

    MySQL表鎖、行鎖、排它鎖及共用鎖怎麼使用

    MySQL表鎖、行鎖、排它鎖及共用鎖怎麼使用

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

    MySQL表鎖、行鎖、排它鎖及共用鎖怎麼使用

    因為現在name走的是索引, 透過zhangsan在輔助索引樹上找到它所在行記錄的id是7,然後

    到主鍵索引樹上,取得對應行記錄的排他鎖(個人猜測應該是輔助索引樹和主鍵索引樹對應的記錄都加了鎖)

    四、串列化隔離等級測試

    (所有的交易都使用排它鎖定或共用鎖定,不需要使用者手動加鎖)

    設定串列化隔離等級

    MySQL表鎖、行鎖、排它鎖及共用鎖怎麼使用

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

    MySQL表鎖、行鎖、排它鎖及共用鎖怎麼使用

    #現在讓事務2插入資料

    MySQL表鎖、行鎖、排它鎖及共用鎖怎麼使用

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

    rollback一下

    MySQL表鎖、行鎖、排它鎖及共用鎖怎麼使用

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

    交易2 update

    MySQL表鎖、行鎖、排它鎖及共用鎖怎麼使用

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

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

    MySQL表鎖、行鎖、排它鎖及共用鎖怎麼使用

    我們用主鍵索引id試試看能不能update

    MySQL表鎖、行鎖、排它鎖及共用鎖怎麼使用

    #依然阻塞住了,雖然我們where後面的欄位現在使用的id而不是name,但是name也是透過輔助索引樹找到對應的主鍵,再到主鍵索引樹上找對應的記錄,而主鍵索引樹上的記錄加了鎖

    (個人猜想應該是輔助索引樹和主鍵索引樹對應的資料都加了鎖)

    我們update id=8的數據,成功了。只為id為7的行資料加上了行鎖,因此我們可以成功操作id為8的資料

    MySQL表鎖、行鎖、排它鎖及共用鎖怎麼使用

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

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

    以上是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

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

    熱工具

    記事本++7.3.1

    記事本++7.3.1

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

    SublimeText3漢化版

    SublimeText3漢化版

    中文版,非常好用

    禪工作室 13.0.1

    禪工作室 13.0.1

    強大的PHP整合開發環境

    Dreamweaver CS6

    Dreamweaver CS6

    視覺化網頁開發工具

    SublimeText3 Mac版

    SublimeText3 Mac版

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

    MySQL:世界上最受歡迎的數據庫的簡介 MySQL:世界上最受歡迎的數據庫的簡介 Apr 12, 2025 am 12:18 AM

    MySQL是一種開源的關係型數據庫管理系統,主要用於快速、可靠地存儲和檢索數據。其工作原理包括客戶端請求、查詢解析、執行查詢和返回結果。使用示例包括創建表、插入和查詢數據,以及高級功能如JOIN操作。常見錯誤涉及SQL語法、數據類型和權限問題,優化建議包括使用索引、優化查詢和分錶分區。

    MySQL的位置:數據庫和編程 MySQL的位置:數據庫和編程 Apr 13, 2025 am 12:18 AM

    MySQL在數據庫和編程中的地位非常重要,它是一個開源的關係型數據庫管理系統,廣泛應用於各種應用場景。 1)MySQL提供高效的數據存儲、組織和檢索功能,支持Web、移動和企業級系統。 2)它使用客戶端-服務器架構,支持多種存儲引擎和索引優化。 3)基本用法包括創建表和插入數據,高級用法涉及多表JOIN和復雜查詢。 4)常見問題如SQL語法錯誤和性能問題可以通過EXPLAIN命令和慢查詢日誌調試。 5)性能優化方法包括合理使用索引、優化查詢和使用緩存,最佳實踐包括使用事務和PreparedStatemen

    apache怎麼連接數據庫 apache怎麼連接數據庫 Apr 13, 2025 pm 01:03 PM

    Apache 連接數據庫需要以下步驟:安裝數據庫驅動程序。配置 web.xml 文件以創建連接池。創建 JDBC 數據源,指定連接設置。從 Java 代碼中使用 JDBC API 訪問數據庫,包括獲取連接、創建語句、綁定參數、執行查詢或更新以及處理結果。

    為什麼要使用mysql?利益和優勢 為什麼要使用mysql?利益和優勢 Apr 12, 2025 am 12:17 AM

    選擇MySQL的原因是其性能、可靠性、易用性和社區支持。 1.MySQL提供高效的數據存儲和檢索功能,支持多種數據類型和高級查詢操作。 2.採用客戶端-服務器架構和多種存儲引擎,支持事務和查詢優化。 3.易於使用,支持多種操作系統和編程語言。 4.擁有強大的社區支持,提供豐富的資源和解決方案。

    docker怎麼啟動mysql docker怎麼啟動mysql Apr 15, 2025 pm 12:09 PM

    在 Docker 中啟動 MySQL 的過程包含以下步驟:拉取 MySQL 鏡像創建並啟動容器,設置根用戶密碼並映射端口驗證連接創建數據庫和用戶授予對數據庫的所有權限

    MySQL的角色:Web應用程序中的數據庫 MySQL的角色:Web應用程序中的數據庫 Apr 17, 2025 am 12:23 AM

    MySQL在Web應用中的主要作用是存儲和管理數據。 1.MySQL高效處理用戶信息、產品目錄和交易記錄等數據。 2.通過SQL查詢,開發者能從數據庫提取信息生成動態內容。 3.MySQL基於客戶端-服務器模型工作,確保查詢速度可接受。

    laravel入門實例 laravel入門實例 Apr 18, 2025 pm 12:45 PM

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

    centos7如何安裝mysql centos7如何安裝mysql Apr 14, 2025 pm 08:30 PM

    優雅安裝 MySQL 的關鍵在於添加 MySQL 官方倉庫。具體步驟如下:下載 MySQL 官方 GPG 密鑰,防止釣魚攻擊。添加 MySQL 倉庫文件:rpm -Uvh https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm更新 yum 倉庫緩存:yum update安裝 MySQL:yum install mysql-server啟動 MySQL 服務:systemctl start mysqld設置開機自啟動

    See all articles