搜尋
首頁資料庫mysql教程mysql樂觀鎖和悲觀鎖的差別是什麼

mysql樂觀鎖和悲觀鎖的差別是什麼

Jul 23, 2021 pm 03:17 PM
mysql樂觀鎖悲觀鎖

區別:悲觀鎖定是對於資料的處理持悲觀態度,總認為會發生並發衝突,取得和修改資料時,別人會修改資料;所以在整個資料處理過程中,需要將資料鎖定。樂觀鎖是對資料的處理持樂觀態度,認為一般不會發生衝突,只有在提交資料更新時,才會對資料是否衝突進行偵測。

mysql樂觀鎖和悲觀鎖的差別是什麼

本教學操作環境:windows7系統、mysql8版本、Dell G3電腦。

悲觀鎖與樂觀鎖是人們定義出來的概念,你可以理解為一種思想,是處理並發資源的常用手段。

不要把他們與mysql中提供的鎖機制(表鎖,行鎖,排他鎖,共享鎖)混為一談。

一、悲觀鎖

顧名思義,就是對於資料的處理持悲觀態度,總認為會發生並發衝突,取得和修改資料時,別人會修改數據。所以在整個資料處理過程中,需要將資料鎖定。

悲觀鎖的實現,通常依靠資料庫提供的鎖定機制實現,例如mysql的排他鎖,select .... for update來實現悲觀鎖。

範例:商品秒殺過程中,庫存數量的減少,避免出現超賣的情況。

CREATE TABLE `tb_goods_stock` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `goods_id` bigint(20) unsigned DEFAULT '0' COMMENT '商品ID',
  `nums` int(11) unsigned DEFAULT '0' COMMENT '商品库存数量',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `modify_time` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `goods_id` (`goods_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品库存表';

將商品庫存數量nums欄位類型設為unsigned,保證在資料庫層級不會發生負數的情況。

注意,使用悲觀鎖,需要關閉mysql的自動提交功能,將set autocommit = 0;

注意,mysql中的行級鎖定是基於索引的,如果sql沒有走索引,那將使用表級鎖定整張表鎖住。

1、開啟事務,查詢要賣的商品,並對該記錄加鎖。

begin;select nums from tb_goods_stock where goods_id = {$goods_id} for update;

2、判斷商品數量是否大於購買數量。如果不滿足,就回滾事務。

3、如果符合條件,則減少庫存,並提交事務。

update tb_goods_stock set nums = nums - {$num} where goods_id = {$goods_id} and nums >= {$num};
commit;

交易提交時會釋放交易過程中的鎖定。

悲觀鎖定在同時控制上採取的是先上鎖然後再處理資料的保守策略,雖然保證了資料處理的安全性,但也降低了效率。

二、樂觀鎖

顧名思義,就是對資料的處理持樂觀態度,樂觀的認為資料一般情況下不會發生衝突,只有提交資料更新時,才會對資料是否衝突進行偵測。

如果發現衝突了,則傳回錯誤訊息給用戶,讓用戶自已決定如何操作。

樂觀鎖的實作不依賴資料庫提供的鎖機制,需要我們自已實現,實作方式一般是記錄資料版本,一種是透過版本號,一種是透過時間戳記。

在表格中加上一個版本號或時間戳記的字段,讀取資料時,將版本號一同讀出,資料更新時,將版本號加1。

當我們提交資料更新時,判斷目前的版本號碼與第一次讀取出來的版本號碼是否相等。如果相等,則予以更新,否則認為資料過期,拒絕更新,讓使用者重新操作。

CREATE TABLE `tb_goods_stock` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `goods_id` bigint(20) unsigned DEFAULT '0' COMMENT '商品ID',
  `nums` int(11) unsigned DEFAULT '0' COMMENT '商品库存数量',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `modify_time` datetime DEFAULT NULL COMMENT '更新时间',
  `version` bigint(20) unsigned DEFAULT '0' COMMENT '版本号',
  PRIMARY KEY (`id`),
  UNIQUE KEY `goods_id` (`goods_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT='商品库存表';

1、查詢要賣的商品,並取得版本號。

begin;select nums, version from tb_goods_stock where goods_id = {$goods_id};

2、判斷商品數量是否大於購買數量。如果不滿足,就回滾事務。

3、如果符合條件,則減少庫存。 (更新時判斷當前version與步驟1中取得的version是否相同)

update tb_goods_stock set nums = nums - {$num}, version = version + 1 where goods_id = {$goods_id} and version = {$version} and nums >= {$num};

4、判斷更新操作是否成功執行,如果成功,則提交,否則就回滾。

樂觀鎖定是基於程式實現的,所以不存在死鎖的情況,適用於讀多的應用場景。如果經常發生衝突,上層應用不斷的讓使用者重新操作,反而降低了效能,這種情況下悲觀鎖定就比較適用。

(推薦教學:mysql影片教學

以上是mysql樂觀鎖和悲觀鎖的差別是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
與其他RDBM相比,MySQL如何處理並發?與其他RDBM相比,MySQL如何處理並發?Apr 29, 2025 am 12:44 AM

MySQLhandlesconcurrencyusingamixofrow-levelandtable-levellocking,primarilythroughInnoDB'srow-levellocking.ComparedtootherRDBMS,MySQL'sapproachisefficientformanyusecasesbutmayfacechallengeswithdeadlocksandlacksadvancedfeatureslikePostgreSQL'sSerializa

MySQL與其他關係數據庫相比如何處理交易?MySQL與其他關係數據庫相比如何處理交易?Apr 29, 2025 am 12:37 AM

mySqlHandLestActionSefectefectionalytheinnodbengine,supportingAcidPropertiessimilartopostgresqlesqlandoracle.1)mySqluessRepeTableReadAbereadasTheDefaultIsolationLeleleteLevel,whatcanBeadJustEdToreDtoreDtoreDtoreadCommittedCommittenCommententCommittedForHigh-TrafficsCenarios.2)

MySQL中有哪些數據類型?MySQL中有哪些數據類型?Apr 29, 2025 am 12:28 AM

MySQL的數據類型分為數值、日期和時間、字符串、二進制和空間類型。選擇正確的類型可以優化數據庫性能和數據存儲。

在MySQL中編寫有效的SQL查詢的最佳實踐是什麼?在MySQL中編寫有效的SQL查詢的最佳實踐是什麼?Apr 29, 2025 am 12:24 AM

最佳實踐包括:1)理解數據結構和MySQL處理方式,2)適當索引,3)避免SELECT*,4)使用合適的JOIN類型,5)謹慎使用子查詢,6)使用EXPLAIN分析查詢,7)考慮查詢對服務器資源的影響,8)定期維護數據庫。這些做法能使MySQL查詢不僅快速,還具備可維護性、可擴展性和資源效率。

MySQL與PostgreSQL有何不同?MySQL與PostgreSQL有何不同?Apr 29, 2025 am 12:23 AM

MySQLisbetterforspeedandsimplicity,suitableforwebapplications;PostgreSQLexcelsincomplexdatascenarioswithrobustfeatures.MySQLisidealforquickprojectsandread-heavytasks,whilePostgreSQLispreferredforapplicationsrequiringstrictdataintegrityandadvancedSQLf

MySQL如何處理數據複製?MySQL如何處理數據複製?Apr 28, 2025 am 12:25 AM

MySQL通過異步、半同步和組複製三種模式處理數據複製。 1)異步複製性能高但可能丟失數據。 2)半同步複製提高數據安全性但增加延遲。 3)組複製支持多主複製和故障轉移,適用於高可用性需求。

您如何使用解釋性語句分析查詢性能?您如何使用解釋性語句分析查詢性能?Apr 28, 2025 am 12:24 AM

EXPLAIN語句可用於分析和提升SQL查詢性能。 1.執行EXPLAIN語句查看查詢計劃。 2.分析輸出結果,關注訪問類型、索引使用情況和JOIN順序。 3.根據分析結果,創建或調整索引,優化JOIN操作,避免全表掃描,以提升查詢效率。

您如何備份並還原MySQL數據庫?您如何備份並還原MySQL數據庫?Apr 28, 2025 am 12:23 AM

使用mysqldump進行邏輯備份和MySQLEnterpriseBackup進行熱備份是備份MySQL數據庫的有效方法。 1.使用mysqldump備份數據庫:mysqldump-uroot-pmydatabase>mydatabase_backup.sql。 2.使用MySQLEnterpriseBackup進行熱備份:mysqlbackup--user=root--password=password--backup-dir=/path/to/backupbackup。恢復時,使用相應的命

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具