偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

聊聊樂(lè)觀鎖與悲觀鎖

開(kāi)發(fā) 前端
MySQL中的樂(lè)觀鎖主要通過(guò)CAS(Compare and Swap)的機(jī)制來(lái)實(shí)現(xiàn),通常使用版本號(hào)(version)來(lái)實(shí)現(xiàn)。

悲觀鎖

在MySQL中,悲觀鎖依賴(lài)數(shù)據(jù)庫(kù)提供的鎖機(jī)制來(lái)實(shí)現(xiàn)。在InnoDB引擎中,使用悲觀鎖需要先關(guān)閉MySQL數(shù)據(jù)庫(kù)的自動(dòng)提交屬性,然后通過(guò)select ... for update來(lái)進(jìn)行加鎖。

在數(shù)據(jù)庫(kù)中,悲觀鎖的流程如下:

? 在對(duì)記錄進(jìn)行修改前,先嘗試為該記錄加上排他鎖(exclusive lock)。

? 如果加鎖失敗,說(shuō)明該記錄正在被修改,此時(shí)當(dāng)前查詢(xún)可能需要等待或拋出異常,具體響應(yīng)方式由開(kāi)發(fā)者根據(jù)實(shí)際需求決定。

? 如果成功加鎖,則可以對(duì)記錄進(jìn)行修改,事務(wù)完成后鎖將被釋放。

? 其間若有其他操作試圖對(duì)該記錄進(jìn)行修改或加排他鎖,則會(huì)等待當(dāng)前鎖的釋放或直接拋出異常。

我們以電商平臺(tái)下單過(guò)程中扣減庫(kù)存的需求為例,說(shuō)明如何使用悲觀鎖:

-- 0.開(kāi)始事務(wù)
begin; 
-- 1.查詢(xún)出商品信息
SELECT stock FROM products WHERE product_id = 12345 FOR UPDATE;
-- 2.修改商品stock為2
update products set stock=2 where product_id = 12345;
-- 3.提交事務(wù)
commit;

在對(duì)id=1的記錄進(jìn)行修改前,先通過(guò)FOR UPDATE的方式加鎖,然后再進(jìn)行修改。這就是典型的悲觀鎖策略。

如果上述修改庫(kù)存的代碼發(fā)生并發(fā),同一時(shí)間只有一個(gè)線程可以開(kāi)啟事務(wù)并獲得id=1的鎖,其他事務(wù)必須等本次事務(wù)提交之后才能執(zhí)行。這樣,我們可以保證當(dāng)前的數(shù)據(jù)不會(huì)被其他事務(wù)修改。

上面提到,使用SELECT ... FOR UPDATE會(huì)將數(shù)據(jù)鎖住,不過(guò)我們需要注意一些鎖的級(jí)別。MySQL InnoDB默認(rèn)使用行級(jí)鎖。行級(jí)鎖都是基于索引的,如果一條SQL語(yǔ)句未使用索引,優(yōu)化器在選擇時(shí),若發(fā)現(xiàn)鎖表可能性能更好,有可能會(huì)直接鎖表。

上面這個(gè)點(diǎn)之前也有在文章提到過(guò): 

日活3kw的實(shí)際庫(kù)存業(yè)務(wù)場(chǎng)景中的超賣(mài)到底怎么解決的

感興趣的可以參考閱讀一下,希望對(duì)你有所幫助

樂(lè)觀鎖

MySQL中的樂(lè)觀鎖主要通過(guò)CAS(Compare and Swap)的機(jī)制來(lái)實(shí)現(xiàn),通常使用版本號(hào)(version)來(lái)實(shí)現(xiàn)。

CAS是一種樂(lè)觀鎖技術(shù),當(dāng)多個(gè)線程嘗試使用CAS同時(shí)更新同一個(gè)變量時(shí),只有其中一個(gè)線程能成功更新變量的值,而其他線程都失敗。失敗的線程并不會(huì)被掛起,而是被告知在此次競(jìng)爭(zhēng)中失敗,并可以再次嘗試。

以扣減庫(kù)存為例,通過(guò)樂(lè)觀鎖可以實(shí)現(xiàn)如下:

-- 查詢(xún)出商品信息,stock = 3
select stock from products product_id id= 1
-- 根據(jù)商品信息生成訂單
-- 修改商品stock為2
update products set stock=2 where id=1 and stock = 3;

以上,在更新之前,先查詢(xún)庫(kù)存表中當(dāng)前的庫(kù)存數(shù)(stock),然后在執(zhí)行更新時(shí),將庫(kù)存數(shù)作為修改條件。提交更新時(shí),對(duì)比數(shù)據(jù)庫(kù)表記錄的當(dāng)前庫(kù)存數(shù)與第一次查詢(xún)得到的庫(kù)存數(shù),若兩者相等,則執(zhí)行更新;否則,視為數(shù)據(jù)已過(guò)期。

題外話(huà)

悲觀鎖

在對(duì)數(shù)據(jù)庫(kù)中的數(shù)據(jù)進(jìn)行修改時(shí),為了避免同時(shí)被其他人修改,最好的方法是直接對(duì)該數(shù)據(jù)進(jìn)行加鎖以防止并發(fā)。這種在修改數(shù)據(jù)之前先鎖定再修改的方式被稱(chēng)為悲觀并發(fā)控制(又稱(chēng)“悲觀鎖”,Pessimistic Concurrency Control,縮寫(xiě)為“PCC”)。

悲觀鎖之所以被稱(chēng)為悲觀,是因?yàn)檫@是一種對(duì)數(shù)據(jù)的修改抱有悲觀態(tài)度的并發(fā)控制方式。一般來(lái)說(shuō),我們認(rèn)為數(shù)據(jù)被并發(fā)修改的概率較大,因此在修改之前先加鎖。

悲觀并發(fā)控制實(shí)際上是一種保守的策略,即“先取鎖再訪問(wèn)”,它為數(shù)據(jù)處理的安全性提供了保證。

圖片圖片

在效率方面,處理加鎖機(jī)制會(huì)導(dǎo)致數(shù)據(jù)庫(kù)產(chǎn)生額外的開(kāi)銷(xiāo),增加了產(chǎn)生死鎖的風(fēng)險(xiǎn)。此外,悲觀鎖還可能降低并行性,因?yàn)槿绻粋€(gè)事務(wù)鎖定了某行數(shù)據(jù),其他事務(wù)就必須等待該事務(wù)完成才能處理該行數(shù)據(jù)。

樂(lè)觀鎖

樂(lè)觀鎖(Optimistic Locking)是相對(duì)悲觀鎖而言的。樂(lè)觀鎖假設(shè)數(shù)據(jù)在一般情況下不會(huì)發(fā)生沖突,因此在數(shù)據(jù)提交更新時(shí)才會(huì)實(shí)際檢查數(shù)據(jù)是否沖突。如果發(fā)現(xiàn)沖突,則會(huì)向用戶(hù)返回錯(cuò)誤信息,讓用戶(hù)決定如何處理。

與悲觀鎖相比,樂(lè)觀鎖在處理數(shù)據(jù)庫(kù)時(shí)并不會(huì)使用數(shù)據(jù)庫(kù)提供的鎖機(jī)制。一般來(lái)說(shuō),樂(lè)觀鎖的實(shí)現(xiàn)方式是通過(guò)記錄數(shù)據(jù)的版本信息。

圖片圖片

樂(lè)觀并發(fā)控制相信事務(wù)之間的數(shù)據(jù)競(jìng)爭(zhēng)(data race)的概率較小,因此盡可能直接進(jìn)行操作,直到提交時(shí)才對(duì)數(shù)據(jù)進(jìn)行檢查和鎖定。這樣做不會(huì)產(chǎn)生任何鎖或死鎖。

如何選擇

在樂(lè)觀鎖與悲觀鎖的選擇上面,主要看下兩者的區(qū)別以及適用場(chǎng)景就可以了。

1. 樂(lè)觀鎖并未真正加鎖,效率高。適用于讀操作頻繁,寫(xiě)操作相對(duì)較少的場(chǎng)景。一旦鎖的粒度掌握不好,更新失敗的概率就會(huì)比較高,容易發(fā)生業(yè)務(wù)失敗。

2. 悲觀鎖依賴(lài)數(shù)據(jù)庫(kù)鎖,效率低。更新失敗的概率比較低。適用于寫(xiě)操作較為頻繁,且并發(fā)寫(xiě)入的概率較高的場(chǎng)景。

根據(jù)以上區(qū)別和場(chǎng)景特點(diǎn),可以針對(duì)具體業(yè)務(wù)需求選擇合適的并發(fā)控制策略。當(dāng)然最多的場(chǎng)景其實(shí)當(dāng)屬于高并發(fā)場(chǎng)景如何選擇。

責(zé)任編輯:武曉燕 來(lái)源: 碼上遇見(jiàn)你
相關(guān)推薦

2023-02-23 10:32:52

樂(lè)觀鎖

2021-03-30 09:45:11

悲觀鎖樂(lè)觀鎖Optimistic

2025-04-23 08:45:00

悲觀鎖樂(lè)觀鎖并發(fā)控制機(jī)制

2024-09-03 15:14:42

2024-01-29 01:08:01

悲觀鎖遞歸鎖讀寫(xiě)鎖

2024-07-25 09:01:22

2023-07-05 08:18:54

Atomic類(lèi)樂(lè)觀鎖悲觀鎖

2011-08-18 13:44:42

Oracle悲觀鎖樂(lè)觀鎖

2019-04-19 09:48:53

樂(lè)觀鎖悲觀鎖數(shù)據(jù)庫(kù)

2019-11-28 16:00:06

重入鎖讀寫(xiě)鎖樂(lè)觀鎖

2009-09-25 16:43:44

Hibernate悲觀Hibernate樂(lè)觀

2019-05-05 10:15:42

悲觀鎖樂(lè)觀鎖數(shù)據(jù)安全

2019-01-04 11:18:35

獨(dú)享鎖共享鎖非公平鎖

2020-07-06 08:03:32

Java悲觀鎖樂(lè)觀鎖

2018-07-31 10:10:06

MySQLInnoDB死鎖

2023-08-17 14:10:11

Java開(kāi)發(fā)前端

2010-08-18 09:00:38

數(shù)據(jù)庫(kù)

2020-09-16 07:56:28

多線程讀寫(xiě)鎖悲觀鎖

2020-10-22 08:21:37

樂(lè)觀鎖、悲觀鎖和MVC

2024-01-05 16:43:30

數(shù)據(jù)庫(kù)線程
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)