關(guān)于for update和lock in share mode的區(qū)別及說(shuō)明
lock in share mode 就是共享鎖
如果事務(wù)對(duì)某行數(shù)據(jù)加上共享鎖之后,可進(jìn)行讀寫操作;其他事務(wù)可以對(duì)該數(shù)據(jù)加共享鎖,但不能加排他鎖,且只能讀數(shù)據(jù),不能修改數(shù)據(jù)。
某個(gè)事物想進(jìn)行修改數(shù)據(jù)操作,那他必須等其他事物的共享鎖都釋放完畢才能進(jìn)行修改操作
for update 排他鎖,就是行鎖
如果事務(wù)對(duì)數(shù)據(jù)加上排他鎖之后,則其他事務(wù)不能對(duì)該數(shù)據(jù)加任何的鎖。
獲取排他鎖的事務(wù)既能讀取數(shù)據(jù),也能修改數(shù)據(jù)。
注:普通 select 語(yǔ)句默認(rèn)不加鎖,而CUD操作默認(rèn)加排他鎖。
例子
下面例子的前提都是針對(duì)同一行數(shù)據(jù)。
1.同一行數(shù)據(jù)為前提,兩個(gè)事物都進(jìn)行共享鎖查詢


2.同一行數(shù)據(jù)為前提,一個(gè)事物進(jìn)行共享鎖查詢,另一個(gè)事物進(jìn)行修改


第一個(gè)占有著共享鎖,第二個(gè)事物沒(méi)法更新,必須等第一個(gè)事物釋放才能進(jìn)行更新
3.同一行數(shù)據(jù)為前提,一個(gè)進(jìn)行共享鎖查詢,另一個(gè)先進(jìn)行共享鎖查詢,然后update


同第二種,修改的事物就一直在轉(zhuǎn)圈圈,等待事物1提交。事物1不提交,那事物2只能等到超時(shí)返回錯(cuò)誤。
4.同一行數(shù)據(jù)為前提,當(dāng)事物一獲得共享鎖,另一個(gè)事物是否可以獲得排它鎖


答案是不能,事物二就一直轉(zhuǎn)圈圈,等待1的釋放
結(jié)論:同一行數(shù)據(jù)為前提,當(dāng)一個(gè)事物獲得共享鎖,另一個(gè)事物可以獲得共享鎖進(jìn)行讀操作,但不能進(jìn)行修改操作,想要修改必須等其他的共享鎖釋放完畢。還有一個(gè)事物獲得了共享鎖,另一個(gè)事物不能獲得排它鎖
5.同一行數(shù)據(jù)為前提,一個(gè)事物獲取到排他鎖,另一個(gè)事物進(jìn)行查詢


結(jié)果是可以的,一個(gè)獲取排它鎖,另一個(gè)進(jìn)行普通查詢
6.同一行數(shù)據(jù)為前提,一個(gè)事物獲取到排他鎖,另一個(gè)事物進(jìn)行共享鎖的獲取


結(jié)果如圖2,愛(ài)的魔力轉(zhuǎn)圈圈,就一直卡在那里
7.同一行數(shù)據(jù)為前提,一個(gè)事物獲取排它鎖,另一個(gè)事物是否可以進(jìn)行修改


結(jié)果如圖2,愛(ài)的魔力轉(zhuǎn)圈圈,就一直卡在那里
8.同一行數(shù)據(jù)為前提,一個(gè)事物獲取排它鎖,另一個(gè)是否可以獲取排它鎖


結(jié)果如圖2,愛(ài)的魔力轉(zhuǎn)圈圈,就一直卡在那里
結(jié)論:當(dāng)前事務(wù)獲取某行數(shù)據(jù)排他鎖后,其他事務(wù)是否可以對(duì)該行數(shù)據(jù)進(jìn)行讀寫操作和獲取共享鎖:其他事務(wù)可以讀,不可以獲取共享鎖,不可以寫
這里再給讀者科普一點(diǎn),行鎖和索引的關(guān)系:查詢字段未加索引(主鍵索引、普通索引等)時(shí),使用表鎖
注:InnoDB行級(jí)鎖基于索引實(shí)現(xiàn)。
未加索引時(shí),兩種行鎖情況為(使用表鎖):
- 事務(wù)1獲取某行數(shù)據(jù)共享鎖,其他事務(wù)可以獲取不同行數(shù)據(jù)的共享鎖,不可以獲取不同行數(shù)據(jù)的排他鎖
- 事務(wù)1獲取某行數(shù)據(jù)排他鎖,其他事務(wù)不可以獲取不同行數(shù)據(jù)的共享鎖、排他鎖
加索引后,兩種行鎖為(使用行鎖):
- 事務(wù)1獲取某行數(shù)據(jù)共享鎖,其他事務(wù)可以獲取不同行數(shù)據(jù)的排他鎖
- 事務(wù)1獲取某行數(shù)據(jù)排他鎖,其他事務(wù)可以獲取不同行數(shù)據(jù)的共享鎖、排他鎖
表結(jié)果:
CREATE TABLE `pf_banner` ( `id` bigint(22) NOT NULL AUTO_INCREMENT, `num` int(11) DEFAULT NULL, `title` varchar(80) DEFAULT NULL, `url` varchar(255) DEFAULT NULL, `img` varchar(255) DEFAULT NULL, `status` tinyint(4) DEFAULT '1' COMMENT '狀態(tài) 1:顯示 -1不顯示', `create_time` datetime DEFAULT NULL, `modify_time` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='banner位圖片'
例子
1.未加索引,事務(wù)1獲取某行數(shù)據(jù)共享鎖,事務(wù)2更新不同行數(shù)據(jù)阻塞:


2.未加索引,事務(wù)1獲取某行數(shù)據(jù)共享鎖,事務(wù)2獲取不同行數(shù)據(jù)共享鎖成功:


3.未加索引,事務(wù)1獲取某行數(shù)據(jù)排他鎖,事務(wù)2獲取不同行數(shù)據(jù)共享鎖阻塞:


4.未加索引,事務(wù)1獲取某行數(shù)據(jù)排他鎖,事務(wù)2獲取不同行數(shù)據(jù)排他鎖阻塞:


加索引后表結(jié)構(gòu):
CREATE TABLE `pf_banner` ( `id` bigint(22) NOT NULL AUTO_INCREMENT, `num` int(11) DEFAULT NULL, `title` varchar(80) DEFAULT NULL, `url` varchar(255) DEFAULT NULL, `img` varchar(255) DEFAULT NULL, `status` tinyint(4) DEFAULT '1' COMMENT '狀態(tài) 1:顯示 -1不顯示', `create_time` datetime DEFAULT NULL, `modify_time` datetime DEFAULT NULL, PRIMARY KEY (`id`), KEY `idx_num` (`num`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='banner位圖片'
1.加索引后,事務(wù)1獲取某行數(shù)據(jù)共享鎖,事務(wù)2可以更新不同行數(shù)據(jù):


2.加索引后,事務(wù)1獲取某行數(shù)據(jù)共享鎖,事務(wù)2獲取不同行數(shù)據(jù)共享鎖成功:


3.加索引后,事務(wù)1獲取某行數(shù)據(jù)排他鎖,事務(wù)2獲取不同行數(shù)據(jù)排他鎖成功:


4.加索引后,事務(wù)1獲取某行數(shù)據(jù)排他鎖,事務(wù)2獲取不同行數(shù)據(jù)共享鎖成功:


科普小知識(shí)2:索引數(shù)據(jù)重復(fù)率太高會(huì)導(dǎo)致全表掃描:當(dāng)表中索引字段數(shù)據(jù)重復(fù)率太高,則MySQL可能會(huì)忽略索引,進(jìn)行全表掃描,此時(shí)使用表鎖??墒褂?force index 強(qiáng)制使用索引。

操作步驟
1.事務(wù)1,執(zhí)行鼠標(biāo)選中的內(nèi)容
2.事物2,執(zhí)行鼠標(biāo)選中的內(nèi)容


你會(huì)發(fā)現(xiàn)事物2會(huì)一直轉(zhuǎn)圈圈,其實(shí)在執(zhí)行update的時(shí)候,已經(jīng)是表鎖了。導(dǎo)致事物2 進(jìn)行行鎖的時(shí)候,需要等待事物1的釋放
現(xiàn)在,我們使用強(qiáng)制鎖進(jìn)行更新操作。


當(dāng)你使用強(qiáng)制索引的時(shí)候,就會(huì)發(fā)現(xiàn)更新成功了。
當(dāng)然數(shù)據(jù)重復(fù)降低,也是能成功的



總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
mysql關(guān)聯(lián)兩張表時(shí)的編碼問(wèn)題及解決辦法
在本篇文章里小編給大家整理的是關(guān)于mysql關(guān)聯(lián)兩張表時(shí)的編碼問(wèn)題及解決辦法,有需要的朋友們可以參考下。2019-09-09
Mysql8.4.3LTS中離線部署的實(shí)現(xiàn)示例
本文詳細(xì)介紹了在Ubuntu 24.04系統(tǒng)上離線部署MySQL 8.4.3 LTS,包括環(huán)境配置、安裝步驟等步驟,對(duì)小白有一定的幫助,感興趣的可以了解一下2024-11-11
MySQL 存儲(chǔ)過(guò)程傳參數(shù)實(shí)現(xiàn)where id in(1,2,3,...)示例
一個(gè)MySQL 存儲(chǔ)過(guò)程傳參數(shù)的問(wèn)題想實(shí)現(xiàn)例如篩選條件為:where id in(1,2,3,...),下面有個(gè)不錯(cuò)的示例,感興趣的朋友可以參考下2013-10-10
運(yùn)用mysqldump 工具時(shí)需要注意的問(wèn)題
用mysqldump 導(dǎo)出 Trigger 的時(shí)候遇到一個(gè)問(wèn)題,貼出來(lái),以免大家犯錯(cuò)。2009-07-07
MySQL中使用load data命令實(shí)現(xiàn)數(shù)據(jù)導(dǎo)入的方法
MySQL支持load data命令的數(shù)據(jù)導(dǎo)入,該方式比直接的insert的效率要高,按照官方的說(shuō)法是要比insert語(yǔ)句快上20倍2013-10-10
MySQL中實(shí)現(xiàn)高性能高并發(fā)計(jì)數(shù)器方案(例如文章點(diǎn)擊數(shù))
這篇文章主要介紹了MySQL中實(shí)現(xiàn)高性能高并發(fā)計(jì)數(shù)器方案,本文中的計(jì)數(shù)器是指如文章的點(diǎn)擊數(shù)、喜歡數(shù)、瀏覽次數(shù)等,需要的朋友可以參考下2014-10-10

