本文小編為大家詳細(xì)介紹“MySQL鎖機(jī)制的概念是什么”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“mysql鎖機(jī)制的概念是什么”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學(xué)習(xí)新知識(shí)吧。
目前成都創(chuàng)新互聯(lián)公司已為上千的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)站空間、網(wǎng)站運(yùn)營、企業(yè)網(wǎng)站設(shè)計(jì)、西區(qū)網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。
在多線程當(dāng)中如果想保證數(shù)據(jù)的準(zhǔn)確性是如何實(shí)現(xiàn)的呢?沒錯(cuò),通過同步實(shí)現(xiàn)。同步就相當(dāng)于是加鎖。加了鎖以后有什么好處呢?當(dāng)一個(gè)線程真正在操作數(shù)據(jù)的時(shí)候,其他線程只能等待。當(dāng)一個(gè)線程執(zhí)行完畢后,釋放鎖。其他線程才能進(jìn)行操作!
那么我們的MySQL數(shù)據(jù)庫中的鎖的功能也是類似的,處理事務(wù)的隔離性中,可能會(huì)出現(xiàn)臟讀、不可重復(fù)讀、幻讀的問題,所以,鎖的作用也可以解決這些問題!
在數(shù)據(jù)庫中,數(shù)據(jù)是一種供許多用戶共享訪問的資源,如何保證數(shù)據(jù)并發(fā)訪問的一致性、有效性,是所有數(shù)據(jù)庫必須解決的一個(gè)問題,MySQL由于自身架構(gòu)的特點(diǎn),在不同的存儲(chǔ)引擎中,都設(shè)計(jì)了面對(duì)特定場(chǎng)景的鎖定機(jī)制,所以引擎的差別,導(dǎo)致鎖機(jī)制也是有很大差別的。
數(shù)據(jù)庫為了保證數(shù)據(jù)的一致性,而使用各種共享的資源在被并發(fā)訪問時(shí)變得有序所設(shè)計(jì)的一種規(guī)則。
舉例:在電商網(wǎng)站購買商品時(shí),商品表中只存有1個(gè)商品,而此時(shí)又有兩個(gè)人同時(shí)購買,那么誰能買到就是一個(gè)關(guān)鍵的問題。
這里會(huì)用到事務(wù)進(jìn)行一系列的操作:
先從商品表中取出物品的數(shù)據(jù)
然后插入訂單
付款后,再插入付款表信息
更新商品表中商品的數(shù)量
以上過程中,使用鎖可以對(duì)商品數(shù)量數(shù)據(jù)信息進(jìn)行保護(hù),實(shí)現(xiàn)隔離,即只允許第一位用戶完成整套購買流程,而其他用戶只能等待,這樣就解決了并發(fā)中的矛盾問題。
按操作分類:
共享鎖:也叫讀鎖。針對(duì)同一份數(shù)據(jù),多個(gè)事務(wù)讀取操作可以同時(shí)加鎖而不互相影響 ,但是不能修改數(shù)據(jù)記錄。
排他鎖:也叫寫鎖。當(dāng)前的操作沒有完成前,會(huì)阻斷其他操作的讀取和寫入
按粒度分類:
表級(jí)鎖:操作時(shí),會(huì)鎖定整個(gè)表。開銷小,加鎖快;不會(huì)出現(xiàn)死鎖;鎖定力度大,發(fā)生鎖沖突概率高,并發(fā)度最低。偏向于MyISAM存儲(chǔ)引擎!
行級(jí)鎖:操作時(shí),會(huì)鎖定當(dāng)前操作行。開銷大,加鎖慢;會(huì)出現(xiàn)死鎖;鎖定粒度小,發(fā)生鎖沖突的概率低,并發(fā)度高。偏向于InnoDB存儲(chǔ)引擎!
頁級(jí)鎖:鎖的粒度、發(fā)生沖突的概率和加鎖的開銷介于表鎖和行鎖之間,會(huì)出現(xiàn)死鎖,并發(fā)性能一般。
按使用方式分類:
悲觀鎖:每次查詢數(shù)據(jù)時(shí)都認(rèn)為別人會(huì)修改,很悲觀,所以查詢時(shí)加鎖。
樂觀鎖:每次查詢數(shù)據(jù)時(shí)都認(rèn)為別人不會(huì)修改,很樂觀,但是更新時(shí)會(huì)判斷一下在此期間別人有沒有去更新這個(gè)數(shù)據(jù)
不同存儲(chǔ)引擎支持的鎖
多個(gè)共享鎖之間可以共享,如果是有鍵的話InnoDB默認(rèn)是行鎖,沒有的話就會(huì)提升到表鎖,是行鎖時(shí)多個(gè)窗口可以修改不同行的數(shù)據(jù),同行的話需要等先加鎖的提交,不同行可以直接修改,但是另外一個(gè)要查詢也要等后面修改的提交。提交完鎖就消失了
共享鎖:
SELECT語句 LOCK IN SHARE MODE;
窗口1:
- 窗口1 /* 共享鎖:數(shù)據(jù)可以被多個(gè)事務(wù)查詢,但是不能修改 */ -- 開啟事務(wù) START TRANSACTION; -- 查詢id為1的數(shù)據(jù)記錄。加入共享鎖 SELECT * FROM student WHERE id=1 LOCK IN SHARE MODE; -- 查詢分?jǐn)?shù)為99分的數(shù)據(jù)記錄。加入共享鎖 SELECT * FROM student WHERE score=99 LOCK IN SHARE MODE; -- 提交事務(wù) COMMIT;
窗口2:
-- 窗口2 -- 開啟事務(wù) START TRANSACTION; -- 查詢id為1的數(shù)據(jù)記錄(普通查詢,可以查詢) SELECT * FROM student WHERE id=1; -- 查詢id為1的數(shù)據(jù)記錄,并加入共享鎖(可以查詢。共享鎖和共享鎖兼容) SELECT * FROM student WHERE id=1 LOCK IN SHARE MODE; -- 修改id為1的姓名為張三三(不能修改,會(huì)出現(xiàn)鎖的情況。只有窗口1提交事務(wù)后,才能修改成功) UPDATE student SET NAME='張三三' WHERE id = 1; -- 修改id為2的姓名為李四四(修改成功,InnoDB引擎默認(rèn)是行鎖) UPDATE student SET NAME='李四四' WHERE id = 2; -- 修改id為3的姓名為王五五(修改失敗,InnoDB引擎如果不采用帶索引的列加鎖。則會(huì)提升為表鎖) UPDATE student SET NAME='王五五' WHERE id = 3; -- 提交事務(wù) COMMIT;
排他鎖:
在排他鎖執(zhí)行的時(shí)候,其他事務(wù)普通查詢可以,不可以加鎖任何操作
-- 標(biāo)準(zhǔn)語法 SELECT語句 FOR UPDATE;
窗口1:
-- 窗口1 /* 排他鎖:加鎖的數(shù)據(jù),不能被其他事務(wù)加鎖查詢或修改 */ -- 開啟事務(wù) START TRANSACTION; -- 查詢id為1的數(shù)據(jù)記錄,并加入排他鎖 SELECT * FROM student WHERE id=1 FOR UPDATE; -- 提交事務(wù) COMMIT;
窗口2:
-- 窗口2 -- 開啟事務(wù) START TRANSACTION; -- 查詢id為1的數(shù)據(jù)記錄(普通查詢沒問題) SELECT * FROM student WHERE id=1; -- 查詢id為1的數(shù)據(jù)記錄,并加入共享鎖(不能查詢。因?yàn)榕潘i不能和其他鎖共存) SELECT * FROM student WHERE id=1 LOCK IN SHARE MODE; -- 查詢id為1的數(shù)據(jù)記錄,并加入排他鎖(不能查詢。因?yàn)榕潘i不能和其他鎖共存) SELECT * FROM student WHERE id=1 FOR UPDATE; -- 修改id為1的姓名為張三(不能修改,會(huì)出現(xiàn)鎖的情況。只有窗口1提交事務(wù)后,才能修改成功) UPDATE student SET NAME='張三' WHERE id=1; -- 提交事務(wù) COMMIT;
MyISAM讀鎖:
myisam是加整個(gè)表的鎖,讀鎖的時(shí)候,不解鎖的話所有的事務(wù)可以查,不可以有其他任何操作包括本身事務(wù)也不可以操作
-- 加鎖 LOCK TABLE 表名 READ; -- 解鎖(將當(dāng)前會(huì)話所有的表進(jìn)行解鎖) UNLOCK TABLES;
MyISAM寫鎖:
寫鎖的時(shí)候,只要不解鎖其他事務(wù)不可以執(zhí)行任何操作,本身事務(wù)可以操作
-- 標(biāo)準(zhǔn)語法 -- 加鎖 LOCK TABLE 表名 WRITE; -- 解鎖(將當(dāng)前會(huì)話所有的表進(jìn)行解鎖) UNLOCK TABLES;
悲觀鎖:
就是很悲觀,它對(duì)于數(shù)據(jù)被外界修改的操作持保守態(tài)度,認(rèn)為數(shù)據(jù)隨時(shí)會(huì)修改。
整個(gè)數(shù)據(jù)處理中需要將數(shù)據(jù)加鎖。悲觀鎖一般都是依靠關(guān)系型數(shù)據(jù)庫提供的鎖機(jī)制。
行鎖,表鎖不論是讀寫鎖都是悲觀鎖。
樂觀鎖:
就是很樂觀,每次自己操作數(shù)據(jù)的時(shí)候認(rèn)為沒有人會(huì)來修改它,所以不去加鎖。
但是在更新的時(shí)候會(huì)去判斷在此期間數(shù)據(jù)有沒有被修改。
需要用戶自己去實(shí)現(xiàn),不會(huì)發(fā)生并發(fā)搶占資源,只有在提交操作的時(shí)候檢查是否違反數(shù)據(jù)完整性。
樂觀鎖的簡(jiǎn)單實(shí)現(xiàn)方式:
實(shí)現(xiàn)思想:加標(biāo)記去比較,一樣則執(zhí)行,不同則不執(zhí)行
方式一:版本號(hào)
給數(shù)據(jù)表中添加一個(gè)version列,每次更新后都將這個(gè)列的值加1。
讀取數(shù)據(jù)時(shí),將版本號(hào)讀取出來,在執(zhí)行更新的時(shí)候,比較版本號(hào)。
如果相同則執(zhí)行更新,如果不相同,說明此條數(shù)據(jù)已經(jīng)發(fā)生了變化。
用戶自行根據(jù)這個(gè)通知來決定怎么處理,比如重新開始一遍,或者放棄本次更新。
-- 創(chuàng)建city表 CREATE TABLE city( id INT PRIMARY KEY AUTO_INCREMENT, -- 城市id NAME VARCHAR(20), -- 城市名稱 VERSION INT -- 版本號(hào) ); -- 添加數(shù)據(jù) INSERT INTO city VALUES (NULL,'北京',1),(NULL,'上海',1),(NULL,'廣州',1),(NULL,'深圳',1); -- 修改北京為北京市 -- 1.查詢北京的version SELECT VERSION FROM city WHERE NAME='北京'; -- 2.修改北京為北京市,版本號(hào)+1。并對(duì)比版本號(hào) UPDATE city SET NAME='北京市',VERSION=VERSION+1 WHERE NAME='北京' AND VERSION=1;
方式二:時(shí)間戳
和版本號(hào)方式基本一樣,給數(shù)據(jù)表中添加一個(gè)列,名稱無所謂,數(shù)據(jù)類型需要是timestamp
每次更新后都將最新時(shí)間插入到此列。
讀取數(shù)據(jù)時(shí),將時(shí)間讀取出來,在執(zhí)行更新的時(shí)候,比較時(shí)間。
如果相同則執(zhí)行更新,如果不相同,說明此條數(shù)據(jù)已經(jīng)發(fā)生了變化。
悲觀鎖和樂觀鎖使用前提:
對(duì)于讀的操作遠(yuǎn)多于寫的操作的時(shí)候,這時(shí)候一個(gè)更新操作加鎖會(huì)阻塞所有的讀取操作,降低了吞吐量。最后還要釋放鎖,鎖是需要一些開銷的,這時(shí)候可以選擇樂觀鎖。
如果是讀寫比例差距不是非常大或者系統(tǒng)沒有響應(yīng)不及時(shí),吞吐量瓶頸的問題,那就不要去使用樂觀鎖,它增加了復(fù)雜度,也帶來了業(yè)務(wù)額外的風(fēng)險(xiǎn)。這時(shí)候可以選擇悲觀鎖。
讀到這里,這篇“mysql鎖機(jī)制的概念是什么”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識(shí)點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過才能領(lǐng)會(huì),如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
分享文章:mysql鎖機(jī)制的概念是什么
網(wǎng)頁鏈接:http://chinadenli.net/article12/jgipgc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計(jì)、響應(yīng)式網(wǎng)站、網(wǎng)站排名、靜態(tài)網(wǎng)站、外貿(mào)建站、網(wǎng)站導(dǎo)航
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)