国产欧美日韩第一页|日本一二三不卡视频|在线精品小视频,亚洲第一免费播放区,metcn人体亚洲一区,亚洲精品午夜视频

幫助中心 >  技術(shù)知識庫 >  數據庫 >  數據庫管理 >  mysql中樂(lè )觀(guān)鎖、悲觀(guān)鎖、共享鎖、排它鎖、行鎖、表鎖概念總結

mysql中樂(lè )觀(guān)鎖、悲觀(guān)鎖、共享鎖、排它鎖、行鎖、表鎖概念總結

2018-12-30 20:02:47 17880

mysql中樂(lè )觀(guān)鎖、悲觀(guān)鎖、共享鎖、排它鎖、行鎖、表鎖概念總結

我們在操作數據庫的時(shí)候,可能會(huì )由于并發(fā)問(wèn)題而引起的數據的不一致性(數據沖突)

樂(lè )觀(guān)鎖

樂(lè )觀(guān)鎖不是數據庫自帶的,需要我們自己去實(shí)現。樂(lè )觀(guān)鎖是指操作數據庫時(shí)(更新操作),想法很樂(lè )觀(guān),認為這次的操作不會(huì )導致沖突,在操作數據時(shí),并不進(jìn)行任何其他的特殊處理(也就是不加鎖),而在進(jìn)行更新后,再去判斷是否有沖突了。

通常實(shí)現是這樣的:在表中的數據進(jìn)行操作時(shí)(更新),先給數據表加一個(gè)版本(version)字段,每操作一次,將那條記錄的版本號加1。也就是先查詢(xún)出那條記錄,獲取出version字段,如果要對那條記錄進(jìn)行操作(更新),則先判斷此刻version的值是否與剛剛查詢(xún)出來(lái)時(shí)的version的值相等,如果相等,則說(shuō)明這段期間,沒(méi)有其他程序對其進(jìn)行操作,則可以執行更新,將version字段的值加1;如果更新時(shí)發(fā)現此刻的version值與剛剛獲取出來(lái)的version的值不相等,則說(shuō)明這段期間已經(jīng)有其他程序對其進(jìn)行操作了,則不進(jìn)行更新操作。

舉例:

下單操作包括3步驟:

1.查詢(xún)出商品信息

select (status,status,version) from t_goods where id=#{id}

2.根據商品信息生成訂單

3.修改商品status為2

update t_goods

set status=2,version=version+1

where id=#{id} and version=#{version};

除了自己手動(dòng)實(shí)現樂(lè )觀(guān)鎖之外,現在網(wǎng)上許多框架已經(jīng)封裝好了樂(lè )觀(guān)鎖的實(shí)現,如hibernate,需要時(shí),可能自行搜索"hiberate 樂(lè )觀(guān)鎖"試試看。

悲觀(guān)鎖

與樂(lè )觀(guān)鎖相對應的就是悲觀(guān)鎖了。悲觀(guān)鎖就是在操作數據時(shí),認為此操作會(huì )出現數據沖突,所以在進(jìn)行每次操作時(shí)都要通過(guò)獲取鎖才能進(jìn)行對相同數據的操作,這點(diǎn)跟java中的synchronized很相似,所以悲觀(guān)鎖需要耗費較多的時(shí)間。另外與樂(lè )觀(guān)鎖相對應的,悲觀(guān)鎖是由數據庫自己實(shí)現了的,要用的時(shí)候,我們直接調用數據庫的相關(guān)語(yǔ)句就可以了。

說(shuō)到這里,由悲觀(guān)鎖涉及到的另外兩個(gè)鎖概念就出來(lái)了,它們就是共享鎖與排它鎖。共享鎖和排它鎖是悲觀(guān)鎖的不同的實(shí)現,它倆都屬于悲觀(guān)鎖的范疇。

共享鎖

共享鎖指的就是對于多個(gè)不同的事務(wù),對同一個(gè)資源共享同一個(gè)鎖。相當于對于同一把門(mén),它擁有多個(gè)鑰匙一樣。就像這樣,你家有一個(gè)大門(mén),大門(mén)的鑰匙有好幾把,你有一把,你女朋友有一把,你們都可能通過(guò)這把鑰匙進(jìn)入你們家,進(jìn)去啪啪啪啥的,一下理解了哈,沒(méi)錯,這個(gè)就是所謂的共享鎖。

剛剛說(shuō)了,對于悲觀(guān)鎖,一般數據庫已經(jīng)實(shí)現了,共享鎖也屬于悲觀(guān)鎖的一種,那么共享鎖在mysql中是通過(guò)什么命令來(lái)調用呢。通過(guò)查詢(xún)資料,了解到通過(guò)在執行語(yǔ)句后面加上lock in share mode就代表對某些資源加上共享鎖了。

比如,我這里通過(guò)mysql打開(kāi)兩個(gè)查詢(xún)編輯器,在其中開(kāi)啟一個(gè)事務(wù),并不執行commit語(yǔ)句

city表DDL如下:

CREATE TABLE `city` (

`id` bigint(20) NOT NULL AUTO_INCREMENT,

`name` varchar(255) DEFAULT NULL,

`state` varchar(255) DEFAULT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;

mysql中樂(lè )觀(guān)鎖、悲觀(guān)鎖、共享鎖、排它鎖、行鎖、表鎖概念總結


begin;

SELECT * from city where id = "1" lock in share mode;

然后在另一個(gè)查詢(xún)窗口中,對id為1的數據進(jìn)行更新

mysql中樂(lè )觀(guān)鎖、悲觀(guān)鎖、共享鎖、排它鎖、行鎖、表鎖概念總結


update city set name="666" where id ="1";

此時(shí),操作界面進(jìn)入了卡頓狀態(tài),過(guò)幾秒后,也提示錯誤信息

[SQL]update city set name="666" where id ="1";

[Err] 1205 - Lock wait timeout exceeded; try restarting transaction

那么證明,對于id=1的記錄加鎖成功了,在上一條記錄還沒(méi)有commit之前,這條id=1的記錄被鎖住了,只有在上一個(gè)事務(wù)釋放掉鎖后才能進(jìn)行操作,或用共享鎖才能對此數據進(jìn)行操作。

再實(shí)驗一下:

mysql中樂(lè )觀(guān)鎖、悲觀(guān)鎖、共享鎖、排它鎖、行鎖、表鎖概念總結


update city set name="666" where id ="1" lock in share mode;

[Err] 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'lock in share mode' at line 1

加上共享鎖后,也提示錯誤信息了,通過(guò)查詢(xún)資料才知道,對于update,insert,delete語(yǔ)句會(huì )自動(dòng)加排它鎖的原因

于是,我又試了試SELECT * from city where id = "1" lock in share mode;

mysql中樂(lè )觀(guān)鎖、悲觀(guān)鎖、共享鎖、排它鎖、行鎖、表鎖概念總結


這下成功了。

排它鎖

排它鎖與共享鎖相對應,就是指對于多個(gè)不同的事務(wù),對同一個(gè)資源只能有一把鎖。

與共享鎖類(lèi)型,在需要執行的語(yǔ)句后面加上for update就可以了

行鎖

行鎖,由字面意思理解,就是給某一行加上鎖,也就是一條記錄加上鎖。

比如之前演示的共享鎖語(yǔ)句

SELECT * from city where id = "1" lock in share mode;

由于對于city表中,id字段為主鍵,就也相當于索引。執行加鎖時(shí),會(huì )將id這個(gè)索引為1的記錄加上鎖,那么這個(gè)鎖就是行鎖。

表鎖

表鎖,和行鎖相對應,給這個(gè)表加上鎖。


提交成功!非常感謝您的反饋,我們會(huì )繼續努力做到更好!

這條文檔是否有幫助解決問(wèn)題?

非常抱歉未能幫助到您。為了給您提供更好的服務(wù),我們很需要您進(jìn)一步的反饋信息:

在文檔使用中是否遇到以下問(wèn)題:
-->