最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Mysql鎖之共享鎖(讀鎖)和排他鎖(寫鎖)詳解

 更新時間:2023年07月27日 09:55:40   作者:煙雨樓臺笑江湖  
這篇文章主要介紹了Mysql鎖之共享鎖(讀鎖)和排他鎖(寫鎖),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

InnoDB和MyISAM

Mysql在5.5之前默認使用MyISAM存儲引擎,之后使用InnoDB。

查看當前存儲引擎:

show variables like ‘%storage_engine%';

MyISAM操作數(shù)據(jù)都是使用的表鎖,你更新一條記錄就要鎖整個表,導(dǎo)致性能較低,并發(fā)不高。當然它也不會存在死鎖問題。

InnoDB與M有ISAM的最大不同有兩點

  • InnoDB支持事務(wù)
  • InnoDB采用了行級鎖。也就是你需要修改哪行,就可以只鎖定哪行。

在Mysql中,行級鎖并不是直接鎖記錄,而是鎖索引。

索引分為主鍵索引和非主鍵索引兩種,如果一條sql語句操作了主鍵索引,Mysql就會鎖定這條主鍵索引;如果一條語句操作了非主鍵索引,Mysql會先鎖定該非主鍵索引,再鎖定相關(guān)的主鍵索引。

InnoDB行鎖是通過給索引加鎖實現(xiàn)的,如果沒有索引,InnoDB會通過因此的聚簇索引來對記錄加鎖。

也就是說:如果不通過索引條件檢索數(shù)據(jù),那么InnoDB將對表中所有數(shù)據(jù)加鎖,實際效果跟表鎖一樣。因為沒有了索引,找到記錄就得掃描全表,要掃描全表,就得鎖定表。

共享鎖與排他鎖

首先說明:InnoDB引擎默認對update,delete,insert加排它鎖,select語句默認不加鎖

共享鎖

共享鎖shared locks(S鎖)也稱讀鎖:用于不更改或不更新數(shù)據(jù)的操作(只讀操作),可以查看但無法修改和刪除的一種數(shù)據(jù)鎖,如select語句。

如果事務(wù)T對數(shù)據(jù)A加上共享鎖后,則其他事務(wù)只能對數(shù)據(jù)A再加共享鎖,不能加排他鎖。獲準共享鎖的事務(wù)只能讀數(shù)據(jù),不能修改數(shù)據(jù)。共享鎖下其它用戶可以并發(fā)讀取,查詢數(shù)據(jù)。但不能修改,增加,刪除數(shù)據(jù)。資源共享。

加鎖方式

select ... lock in share mode

注意:

  • 對于使用共享鎖的事務(wù),其他事務(wù)只能讀,不可寫
  • 如果執(zhí)行了更新操作則會一直等待,直到當前事務(wù)commit或者rollback
  • 如果當前事務(wù)也執(zhí)行了其他事務(wù)處于等待的那條sql語句,當前事務(wù)將會執(zhí)行成功,而其他事務(wù)會報死鎖
  • 允許其他鎖共存

排它鎖

排它鎖Exclusive Locks(X鎖)也稱寫鎖、獨占鎖:用于數(shù)據(jù)修改操作,例如insert、update或delete。確保不會同時對同一資源進行多重更新。

如果事務(wù)T對數(shù)據(jù)A加上排它鎖后,則其他事務(wù)不能在對A加任何類型的鎖。獲準排他鎖的事務(wù)既能讀數(shù)據(jù),又能修改數(shù)據(jù)。我們在操作數(shù)據(jù)庫的時候,可能會由于并發(fā)問題而引起的數(shù)據(jù)的不一致性(數(shù)據(jù)沖突)

加鎖方式

select ... for update

**for update:**InnoDB默認是行級別的鎖,當有明確指定的主鍵是,使用的是行鎖;否則使用表鎖。使用情況詳細如下:

明確指定主鍵,并且存在此記錄,行級鎖。例如:

-- id是主鍵
select name,age from table_user where id = '1' for update;

明確指定主鍵,若查無記錄,無鎖。例如:

-- id是主鍵,單不存在id = 1的數(shù)據(jù)
select name,age from table_user where id = '1' for update;

無主鍵,表級鎖。例如:

-- age是普通字段
select name,age from table_user where age = 12 for update;

主鍵不明確,表級鎖。例如:

-- id是主鍵,age不是,但數(shù)據(jù)庫
select name,age from table_user where age = 12 and id = '1' for update;

注意:

  • 對于排它鎖的事務(wù),其它事務(wù)可讀,但不可進行更新操作
  • for update僅使用與InnoDB,并且必須開啟事務(wù),在begin和commit之間才生效
  • 當一個事務(wù)進行for update的時候,另一個事務(wù)也有for update時會一直等待,直到之前的事務(wù)commit或rollback或斷開連接釋放鎖才能拿到鎖進行后面的操作(排它鎖不能共存)
  • InnoDB引擎默認對update,delete,insert加排它鎖,select語句默認不加鎖
  • 加過排他鎖的數(shù)據(jù)行在其他事務(wù)中是不能修改數(shù)據(jù)的,也不能通過for update和lock in share mode鎖的方式查詢數(shù)據(jù),但可以直接通過select … from …查詢數(shù)據(jù),因為普通查詢沒有任何鎖機制

樂觀鎖與悲觀鎖

首先說明:樂觀鎖和悲觀鎖都是針對讀(select)來說的。

樂觀鎖

樂觀鎖不是數(shù)據(jù)庫自帶的,需要我們自己去實現(xiàn)。

樂觀鎖是指操作數(shù)據(jù)庫時(更新操作),想法很樂觀,認為這次的操作不會導(dǎo)致沖突,在操作數(shù)據(jù)時,并不進行任何其他的特殊處理(也就是不加鎖),而在進行更新后,再去判斷是否有沖突了。

悲觀鎖

悲觀鎖就是在操作數(shù)據(jù)時,認為此操作會出現(xiàn)數(shù)據(jù)沖突,所以在進行每次操作時都要通過獲取鎖才能進行對相同數(shù)據(jù)的操作,這點跟Java中的synchronized很相似,所以悲觀鎖需要耗費較多的時間。

另外與樂觀鎖相對應(yīng),悲觀鎖是由數(shù)據(jù)庫自己實現(xiàn)了的,要用的時候,我們直接調(diào)用數(shù)據(jù)庫的相關(guān)語句就可以了。

由悲觀鎖涉及到的另外兩個鎖概念,就是共享鎖與排他鎖。共享鎖和排他鎖是悲觀鎖的不同實現(xiàn),它倆都屬于悲觀鎖的范疇。

案例

某商品,用戶購買后庫存應(yīng)-1,而某兩個或多個用戶同時購買,此時三個執(zhí)行程序均同時讀得庫存為“n”,之后進行了一些操作,最后將均執(zhí)行update table set 庫存書 = n - 1,那么,很顯然這是錯誤的。

解決

1.使用悲觀鎖(也就是排他鎖)

  • 程序A在查詢庫存數(shù)時使用排他鎖(select * from table where id = 10 for update)
  • 然后進行后續(xù)操作,包括更新庫存數(shù),最后提交事務(wù)
  • 程序B在查詢庫存數(shù)時,如果A還未釋放排他鎖,程序B將等待。。。
  • 程序C同B。。。

2.使用樂觀鎖(靠表設(shè)計和代碼來實現(xiàn))

一般是在該商品表添加version版本字段或者timestamp時間戳字段

程序A查詢后,執(zhí)行更新變成了:

update table set num = num - 1 and version = 23

這樣,保證了修改的數(shù)據(jù)是和它查詢出來的數(shù)據(jù)是一致的(其他執(zhí)行程序肯定未進行修改)。當然,如果更新失敗,表示在更新操作之前,有其他執(zhí)行程序已經(jīng)更新了該庫存數(shù),那么就可以嘗試重試來保證更新成功。為了盡可能避免更新失敗,可以合理調(diào)整重試次數(shù)(阿里巴巴開發(fā)手冊規(guī)定重試次數(shù)不低于三次)。

樂觀鎖和悲觀鎖的區(qū)別

悲觀鎖實際使用了排他鎖來實現(xiàn)**(select … for update)**。InnoDB加行鎖的前提是:必須是通過索引條件來檢索數(shù)據(jù),否則會切換為表鎖。

因此,悲觀鎖在未通過索引條件檢索數(shù)據(jù)時,會鎖定整張表。導(dǎo)致其他程序不允許**“加鎖的查詢操作”**,影響吞吐。因此,如果在查詢居多的情況下,推薦使用樂觀鎖。

加鎖的查詢操作:加過排他鎖的數(shù)據(jù)行在其他事務(wù)中是不能修改的,也不能通過for update或lock in share mode的加鎖方式查詢,但可以直接通過select … from …查詢數(shù)據(jù),因為普通查詢沒有任何鎖機制。

樂觀鎖更新有可能會失敗,甚至是更新幾次都失敗,這是有風險的。所以如果寫入居多,對吞吐要求不高,可使用悲觀鎖。

結(jié)尾:讀用樂觀鎖,寫用悲觀鎖。

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • MySQL之DATETIME與TIMESTAMP的時間精度問題

    MySQL之DATETIME與TIMESTAMP的時間精度問題

    這篇文章主要介紹了MySQL之DATETIME與TIMESTAMP的時間精度問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • MySQL數(shù)據(jù)庫所在服務(wù)器磁盤滿了的故障分析和解決方法

    MySQL數(shù)據(jù)庫所在服務(wù)器磁盤滿了的故障分析和解決方法

    這篇文章主要給大家介紹了MySQL數(shù)據(jù)庫所在服務(wù)器磁盤滿了的故障分析和解決方法,文中通過代碼示例給大家介紹的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下
    2024-02-02
  • Mysql查詢所有表和字段信息的方法

    Mysql查詢所有表和字段信息的方法

    這篇文章主要介紹了Mysql查詢所有表和字段信息,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-04-04
  • Mysql 5.6使用配置文件my.ini來設(shè)置長時間連接數(shù)據(jù)庫的問題

    Mysql 5.6使用配置文件my.ini來設(shè)置長時間連接數(shù)據(jù)庫的問題

    這篇文章主要介紹了Mysql 5.6使用配置文件my.ini來設(shè)置長時間連接數(shù)據(jù)庫,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-07-07
  • MySQL Select語句是如何執(zhí)行的

    MySQL Select語句是如何執(zhí)行的

    這篇文章主要介紹了MySQL Select語句是如何執(zhí)行的,幫助大家更好的理解和使用MySQL,感興趣的朋友可以了解下
    2020-11-11
  • 實例操作MySQL短鏈接

    實例操作MySQL短鏈接

    在本文里我們給大家總結(jié)了關(guān)于MySQL短鏈接的實操方法和相關(guān)知識點,有需要的朋友們跟著學習下。
    2019-03-03
  • MySQL?半同步復(fù)制頻繁報錯的完美解決方案

    MySQL?半同步復(fù)制頻繁報錯的完美解決方案

    在 MySQL 主從復(fù)制架構(gòu)中,半同步復(fù)制作為保障數(shù)據(jù)一致性的重要機制,其穩(wěn)定性直接影響業(yè)務(wù)數(shù)據(jù)的可靠性,本文將結(jié)合實際案例,通過智能診斷工具與手動排查相結(jié)合的方式,深入解析半同步復(fù)制超時問題的成因與解決方案
    2025-06-06
  • 深入了解mysql長事務(wù)

    深入了解mysql長事務(wù)

    這篇文章主要介紹了mysql長事務(wù)的相關(guān)資料,幫助大家更好的理解和學習mysql,感興趣的朋友可以了解下
    2020-08-08
  • Mysql滿意度調(diào)查分組去除最高最低求平均分的實現(xiàn)思路

    Mysql滿意度調(diào)查分組去除最高最低求平均分的實現(xiàn)思路

    該文章介紹了如何使用SQL查詢實現(xiàn)按部門分組,去除每個部門的最高分和最低分,并計算剩余分數(shù)的平均分,文章詳細描述了實現(xiàn)這一需求的步驟,包括使用窗口函數(shù)、子查詢和CTE等技術(shù),感興趣的朋友跟隨小編一起看看吧
    2025-01-01
  • Mysql數(shù)據(jù)庫的QPS和TPS的意義和計算方法

    Mysql數(shù)據(jù)庫的QPS和TPS的意義和計算方法

    今天小編就為大家分享一篇關(guān)于Mysql數(shù)據(jù)庫的QPS和TPS的意義和計算方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-03-03

最新評論

达孜县| 宜州市| 喀什市| 新津县| 青海省| 梁平县| 通山县| 马关县| 永丰县| 都昌县| 临颍县| 利津县| 洪湖市| 海阳市| 舒兰市| 原平市| 阿克苏市| 莲花县| 清水河县| 宝应县| 华安县| 哈尔滨市| 南通市| 拜泉县| 南投市| 府谷县| 哈密市| 长顺县| 平定县| 永福县| 德惠市| 新津县| 沁水县| 宁陵县| 二手房| 济阳县| 朝阳区| 分宜县| 钦州市| 宜兰市| 阳东县|