欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

mysql中鎖機制的最全面講解

 更新時間:2021年09月17日 10:06:06   作者:coderymy  
大概幾個月之前項目中用到事務,需要保證數據的強一致性,期間也用到了mysql的鎖,所以本文打算總結一下mysql的鎖機制,這篇文章主要給大家介紹了關于mysql中鎖機制的相關資料,需要的朋友可以參考下

前言

根據加鎖的粒度區(qū)分

  • 全局鎖
  • 表級鎖
  • 行鎖
    • 記錄鎖
    • 間隙鎖
    • 臨鍵鎖

根據加鎖的場景

  • 樂觀鎖
  • 悲觀鎖

全局鎖

鎖對象是:整個數據庫實例

Flush tables with read lock (FTWRL)-會讓整個庫處于只讀狀態(tài)

使用場景: 做全庫邏輯備份

全庫邏輯備份

為什么要進行全局鎖才能進行數據備份呢?

就比如售賣,我一張表記錄發(fā)貨,一張表記錄扣款.結果我在備份發(fā)貨記錄表.這個時候有人買東西了,只扣款了但是沒有發(fā)貨記錄.這個顯然是不行的

官方自帶的邏輯備份工具是mysqldump。當mysqldump使用參數–single-transaction的時候,導 數據之前就會啟動一個事務,來確保拿到一致性視圖。而由于MVCC的支持,這個過程中數據是 可以正常更新的。但是這個是基于事務的基礎上的,針對myisam數據引擎就不可用,那么就有可能出現有的表不是基于innoDB的數據引擎

當然,如果全部都是innodb的數據引擎表,那么,還是使用默認的mysqldump增加參數–single-transaction來進行全局邏輯備份的好

FTWRL和set global readonly=true的區(qū)別

  1. readonly會在別的邏輯中參與使用(不同系統(tǒng)不一樣)
  2. ftwrl可以在客戶端鏈接斷開時,自動釋放鎖.防止造成死鎖問題

表級鎖

命令:lock table {tableName} read/write(write比read權限大,能write當然能read),unlock table解鎖

鎖住的資源只允許當前的線程可以執(zhí)行對應的操作.且當前線程只能對鎖住的表進行對應的操作

例如:lock table t1 read,則當前線程只能讀不能寫,其他線程不能讀不能寫

MDL鎖

不需要顯式使用,在訪問表時自動加上(為了防止表結構變更帶來的問題)

在對一張表進行增刪改查時上MDL讀鎖,在對一張表的結構進行變更時上MDL寫鎖

  • MDL讀鎖(共享鎖),鎖之間不互斥.所以可以允許多個線程進行同時的增刪改查
  • MDL寫鎖(排它鎖),這個鎖和其他讀寫鎖都互斥.也就是當前數據變更或者查詢或者結構變更,都必須等其他的MDL寫鎖釋放后才能執(zhí)行

行鎖

行鎖是引擎層,各個引擎自己實現的(MyISAM不支持行鎖,所以該引擎只能一次進行一個線程的update操作)

在事務中:行鎖會在需要使用某一行或多行數據時加上,但是所有的行鎖都會在該事務提交才會釋放也就是說,別的線程需要訪問改行數據,就需要等待線程的事務提交之后才能訪問

舉例:

線程A執(zhí)行以下操作
begin;
update t1 set a=1 where id=1;

update t2 set b=2 where id=2;

commit

這個時候線程A分別對t1的id=1上鎖和t2的id=2上鎖.如果此時線程B訪問t1的id=1是無法訪問的,即使第一條語句已經執(zhí)行完成了
線程B只有在線程A進行了commit操作之后才能獲取其中的數據

所以,對于我們來說需要注意的點就是:在進行事務操作時,如果update沒有順序操作,那么就盡量將訪問最多的那條語句最后執(zhí)行(因為上鎖是順序上的,但是釋放鎖是一起釋放的)

特點 表鎖 行鎖
加鎖層面 mysql的server層 數據引擎層
引擎 MyISAM、innoDB InnoDB
特點 不會死鎖、開銷小、加鎖快、鎖粒度大 易死鎖、開銷大、加鎖慢、鎖粒度小

死鎖

很多情況都回引起死鎖,大部分都是針對數據庫操作有問題才會導致.比如

線程A和線程B都針對id=1和id=2進行修改并開啟事務

線程A先修改了id=1導致id=1被線程A上鎖

線程B修改了id=2導致id=2被縣城B上鎖

此時線程A要等待id=2釋放鎖后執(zhí)行對id=2的操作
而線程B要等待id=1釋放鎖后懟id=1的操作

從而達到了一個循環(huán)死鎖的情況

處理這種問題有兩個策略:

  1. 直接進入等待,直到超時。這個超時時間可以通過參數 innodb_lock_wait_timeout(默認50s)來設置。這個不能設置太短,如果不是死鎖呢?
  2. 發(fā)起死鎖檢測,發(fā)現死鎖后,主動回滾死鎖鏈條中的某一個事務,讓其他事 務得以繼續(xù)執(zhí)行。將參數innodb_deadlock_detect設置為on(默認就是on),表示開啟這個邏輯。

記錄鎖

屬于行鎖的一種情況

針對的是事務在加鎖后鎖住的某一條記錄信息

觸發(fā)情況:查詢條件精準命中且命中的條件字段是唯一的

例如:update t1 set name="張三" where id=12138

作用:記錄在被當前事務管理時,加上鎖之后不會被其他事務獲取產生“重復讀”和“數據臟讀”的問題

間隙鎖

屬于行鎖的一種情況

間隙的意思就是between中的數據

在主鍵索引id中有多個數據未填充,這個時候如果兩個線程A和B,A在查詢0-10之間的數據,而B在往id=3插入數據,就會造成數據臟讀的問題

所以在進行between等范圍查找的是事務時候,會加間隙鎖進行約束

臨鍵鎖

臨鍵鎖會把查詢出來的記錄鎖住,同時也會把該范圍查詢內的所有間隙空間也會鎖住,再之它會把相鄰的下一個區(qū)間也會鎖住。

(臨就是相鄰的意思)

樂觀鎖和悲觀鎖

概念 樂觀鎖 悲觀鎖
概念 假定不會發(fā)生并發(fā)沖突
只在提交時判斷下是否有數據問題
假定會發(fā)生并發(fā)沖突
從而上鎖
實現層面 業(yè)務代碼層面,自己實現
(需要結合具體業(yè)務邏輯)
mysql數據庫自身實現
并發(fā)情況 并發(fā)大 并發(fā)小
實現方式 在數據庫中增加版本號字段,
提交時判斷操作前的版本號和當前版本號是否一致
共享鎖:select lock xxxxxx
排它鎖:select xxxx for update
其他 mysql中的synchronized其實就是排它鎖
共享鎖:運行其他線程查不允許增刪改
排它鎖:增刪改都不允許

總結

到此這篇關于mysql中鎖機制的文章就介紹到這了,更多相關mysql鎖機制內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論