OptimisticLock

????????想象你和你的朋友去了一家很受歡迎的餐廳。你們想要點一份特別的菜品——這家餐廳的招牌菜,但因為這道菜非常受歡迎,所以它的狀態可能會隨時變化(比如售罄或重新上架)。

傳統方式(悲觀鎖)

????????通常情況下,服務員會先查看廚房是否還有這道菜(檢查庫存)。如果有,服務員就會立即告訴廚房停止接受更多對該菜品的訂單,并為你們下單。這樣做是為了確保在你們下單期間,沒有人能搶走最后一份這道菜。這就是悲觀鎖的思想——提前鎖定資源以防止其他請求干擾。

樂觀方式

????????但是,這家餐廳采用了更靈活的方式處理訂單。他們允許顧客先選擇菜品并準備好付款,而不立即通知廚房。當你們準備好了要付款時,服務員再去確認一次廚房里是否有這道菜。如果在這段時間內菜品的狀態沒有改變(比如仍然有庫存),那么你們就可以順利下單;但如果菜品已經售罄了,服務員會告訴你們這個消息,并建議你們選擇其他菜品。

這種方法就是樂觀鎖的核心思想:

  • 假設沖突很少發生
    • 大多數時候,你們應該能夠成功點到這道菜,因為在你們選擇菜品和實際下單之間的時間間隔很短,而且餐廳有足夠的庫存。
  • 最后時刻驗證
    • 只有在你們真正決定下單的時候,才會去檢查菜品的狀態是否與之前看到的一致。
  • 沖突處理
    • 如果發現狀態不一致(例如菜品已售罄),則當前操作失敗,需要用戶做出新的選擇。

Java中的樂觀鎖應用

在Java編程中,樂觀鎖通常通過版本號、時間戳或其他標記來實現。下面是一個簡化的示例,展示如何使用版本號來進行樂觀鎖控制:

public class MenuItem {private String name;private int version; // 用于樂觀鎖的版本號public boolean order() {// 獲取最新的菜單項信息MenuItem latest = getLatestMenuItemFromDatabase();// 假設我們從界面上獲取到了用戶選擇時的版本號int userSelectedVersion = getUserSelectedVersion();// 如果版本號匹配,說明自用戶選擇以來沒有其他人修改過這條記錄if (latest.getVersion() == userSelectedVersion) {// 更新數據庫中的記錄并增加版本號updateMenuItemInDatabase(latest, latest.getVersion() + 1);return true; // 訂單成功} else {// 版本號不匹配,說明數據已被修改return false; // 訂單失敗,提示用戶重試}}
}

????????在這個例子中,order() 方法嘗試根據用戶選擇時的版本號來完成訂單。它首先獲取最新的菜單項信息,然后檢查版本號是否匹配。如果匹配,則更新數據庫并增加版本號,表示訂單成功;如果不匹配,則返回 false,意味著訂單由于數據被其他用戶修改而失敗,需要用戶重新選擇或者刷新頁面再試一次。

????????通過這種方式,樂觀鎖允許更高的并發性,因為它不會阻止其他用戶同時訪問相同的數據,只是在最后一步確保數據一致性。如果確實發生了沖突,系統會要求用戶重試他們的操作。這種機制非常適合讀多寫少的應用場景,如在線商店的商品詳情頁、論壇帖子等。

我可以理解 這就是普通的業務判斷是嗎?

????????樂觀鎖不僅僅是簡單的業務判斷,它是一種并發控制策略,用于在多用戶環境下確保數據的一致性和完整性。雖然從表面上看,樂觀鎖的實現可能看起來像是普通的業務邏輯判斷(比如檢查版本號是否匹配),但它背后的理念和作用更為深遠。

樂觀鎖的核心特點

????????假設沖突很少發生:樂觀鎖假定多個事務可以同時進行而不會相互干擾,因此不需要提前鎖定資源。只有在提交時才會檢查是否有沖突發生。

????????最后時刻驗證:當一個事務準備提交時,它會檢查自開始以來該資源的狀態是否發生了變化。如果狀態沒有改變,則允許提交;如果有變化,則認為發生了沖突,事務需要回滾或重試。

????????高并發下的高效性:由于不需要長時間持有鎖,樂觀鎖允許更高的并發度,特別適用于讀操作遠多于寫操作的應用場景

????????輕量級且非阻塞:與悲觀鎖相比,樂觀鎖不涉及鎖機制,因此不會造成線程等待或阻塞的情況,從而提高了系統的響應速度。

????????沖突處理:當檢測到沖突時,通常會提示用戶重新嘗試操作或者系統自動重試。

為什么這不是普通的業務判斷?

????????并發控制:樂觀鎖是專門為了解決并發環境下的數據一致性問題而設計的。它的主要目的是避免多個事務同時修改同一數據而導致的數據不一致或丟失更新的問題。

????????性能優化:通過減少鎖的使用,樂觀鎖可以在高并發的情況下提供更好的性能。相比之下,普通的業務判斷通常不會考慮這些并發問題,也不會試圖優化這種場景下的性能。

????????數據完整性保障:樂觀鎖確保了即使在高并發的情況下,也能維持數據的完整性和一致性,而這并不是普通業務判斷所能提供的保證。

結合上面餐館點餐例子

????????在餐館點餐的例子中,樂觀鎖不僅僅是在最后檢查菜品是否還有庫存(這確實類似于普通的業務判斷)。更重要的是,它允許多位顧客幾乎同時選擇同一道菜而不必擔心其中一方會被無故阻塞。只有到了真正下單的時候,才會去確認菜品的狀態。如果在這期間菜品狀態改變了(例如被其他人訂購完了),那么當前的訂單就會失敗,并提示顧客重新選擇。這種方式既提高了顧客體驗(不必等待),又保證了數據的一致性(避免了超賣)。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/64287.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/64287.shtml
英文地址,請注明出處:http://en.pswp.cn/web/64287.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

10分鐘掌握項目管理核心工具:WBS、甘特圖、關鍵路徑法全解析

一、引言 在項目管理的廣闊天地里,猶如一場精心編排的交響樂演奏,每個樂器、每個音符都需精準配合才能奏響美妙樂章。而 WBS(工作分解結構)、甘特圖、關鍵路徑法無疑是這場交響樂中的關鍵樂章,它們從不同維度為項目管…

TCP 和 UDP 的區別:解析網絡傳輸協議

引言 在計算機網絡的世界中,TCP(Transmission Control Protocol,傳輸控制協議)和 UDP(User Datagram Protocol,用戶數據報協議)是兩種極為重要且應用廣泛的傳輸層協議。它們在功能、特性以及適…

代碼思想之快慢路徑

處理業務代碼的過程中,對業務代碼有了一些調整,后續發現這是一種代碼思想 在一段復雜的邏輯里,我把查詢redis操作寫在了前面, 業務邏輯: 如果需要不打壓就退出本次處理 查詢redis拿到商品需要打壓的次數 如果次數 …

Java 溯本求源之基礎(三十一)——泛型

目錄 1. 泛型的定義與基本概念 2. 泛型的優勢 3. 泛型的基本語法 3.1 泛型類 3.2 泛型方法 3.3 泛型接口 4. 泛型的邊界 4.1 上限通配符(? extends T) 4.2 下限通配符(? super T) 5. 泛型的類型擦除 6. 泛型的使用場景…

純 HTML+CSS+JS 實現一個炫酷的圣誕樹動畫特效

純 HTMLCSSJS 實現一個炫酷的圣誕樹動畫特效 前言 圣誕節快到了,今天給大家帶來一個簡單但是效果不錯的圣誕樹動畫特效。這個特效完全使用原生 HTML、CSS 和 JavaScript 實現,包含閃爍的星星、隨機彩燈等元素,非常適合節日氣氛!…

Maven:Java項目構建與管理的利器

在Java開發領域,Maven無疑是一個舉足輕重的工具。它不僅簡化了項目的構建和依賴管理,還促進了團隊協作和持續集成。本文將深入探討Maven的核心功能、基本配置以及在實際項目中的應用。 Maven簡介 Maven是Apache基金會下的一個開源項目,旨在…

【ES6復習筆記】Promise對象詳解(12)

1. 什么是 Promise? Promise 是 JavaScript 中處理異步操作的一種機制,它可以讓異步操作更加容易管理和控制。Promise 對象代表一個異步操作的最終完成或失敗,并提供了一種方式來處理操作的結果。 2. Promise 的基本語法 Promise 對象有三…

【RAG實戰】語言模型基礎

語言模型賦予了計算機理解和生成人類語言的能力。它結合了統計學原理和深度神經網絡技術,通過對大量的樣本數據進行復雜的概率分布分析來學習語言結構的內在模式和相關性。具體地,語言模型可根據上下文中已出現的詞序列,使用概率推斷來預測接…

【ES6復習筆記】Map(14)

概念 Map 是 JavaScript 中的一種數據結構,它允許你存儲鍵值對,并且可以通過鍵來訪問對應的值。在本教程中,我們將學習如何聲明、添加、刪除、獲取和遍歷 Map 集合。 ES6 提供了 Map 數據結構。它類似于對象,也是鍵值對的集合。…

富芮坤FR800X系列之PWM輸出程序應用設計

文章目錄 前言1.設計背景2.簡介3.如何設計控制調光的接口呢4.硬件設計5.軟件設計5.1.軟件流程圖5.2.軟件代碼 6.小結 前言 版權歸作者所有、未經允許、請勿轉載。 讀者對象: 本文檔主要適用以下工程師: ?嵌入式系統工程師 ?單片機軟件工程師 ?IOT固…

Ftrans數據擺渡系統 搭建安全便捷跨網文件傳輸通道

一、專業數據擺渡系統對企業的意義 專業的數據擺渡系統對企業具有重要意義,主要體現在以下幾個方面?: 1、?數據安全性?:數據擺渡系統通過加密傳輸、訪問控制和審計日志等功能,確保數據在傳輸和存儲過程中的安全性。 2、?高…

EasyPoi 使用$fe:模板語法生成Word動態行

1 Maven 依賴 <dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-spring-boot-starter</artifactId><version>4.0.0</version> </dependency> 2 application.yml spring:main:allow-bean-definition-over…

定義Shape:打造屬于你的獨特圖形

自定義Shape:打造屬于你的獨特圖形 在Android開發中,自定義圖形繪制是一個非常重要的技能,尤其是在需要實現復雜UI或特定設計需求時。Android提供了android.graphics.drawable.shapes包,其中包含了一些基本的形狀類,如RectShape、OvalShape等。然而,有時這些基本形狀無法…

python 滲透開發工具之SQLMapApi Server不同IP服務啟動方式處理 解決方案SqlMapApiServer外網不能訪問的情況

目錄 說在前面 什么是 SQLMapAPI 說明 sqlmapApi能干什么 sqlmapApi 服務安裝相關 kali-sqlmap存放位置 正常啟動sqlmap-api server SqlMapApi-Server 解決外網不能訪問情況 說在前面 什么是sqlmap 這個在前面已經說過了&#xff0c;如果這個不知道&#xff0c;就可以…

【基礎還得練】 KKT 條件

優秀教程-真正理解拉格朗日乘子法和 KKT 條件&#xff1a; link優秀教程-最優化(6)&#xff1a;一般約束優化問題的最優性理論&#xff1a; link KKT條件&#xff08;Karush-Kuhn-Tucker條件&#xff09;是非線性規劃中的一組必要條件&#xff0c;在某些情況下也是最優解的充分…

使用 Webpack 優雅的構建微前端應用?

Module Federation 通常譯作“模塊聯邦”&#xff0c;是 Webpack 5 新引入的一種遠程模塊動態加載、運行技術。MF 允許我們將原本單個巨大應用按我們理想的方式拆分成多個體積更小、職責更內聚的小應用形式&#xff0c;理想情況下各個應用能夠實現獨立部署、獨立開發(不同應用甚…

Boost之log日志使用

不講理論&#xff0c;直接上在程序中可用代碼&#xff1a; 一、引入Boost模塊 開發環境&#xff1a;Visual Studio 2017 Boost庫版本&#xff1a;1.68.0 安裝方式&#xff1a;Nuget 安裝命令&#xff1a; #只安裝下面幾個即可 Install-package boost -version 1.68.0 Install…

【MySQL】十四,MySQL 8.0的隱藏索引

在MySQL 8.0之前的版本中&#xff0c;索引只能直接刪除。如果刪除后發現引起了系統故障&#xff0c;又必須進行創建。當表的數據量比較大的時候&#xff0c;這樣做的代價就會非常高。 在MySQL 8.0中&#xff0c;提供了隱藏索引。如果想刪除某個索引&#xff0c;那么在實際刪除…

【ES6復習筆記】解構賦值(2)

介紹 解構賦值是一種非常方便的語法&#xff0c;可以讓我們更簡潔地從數組和對象中提取值&#xff0c;并且可以應用于很多實際開發場景中。 1. 數組的解構賦值 數組的解構賦值是按照一定模式從數組中提取值&#xff0c;然后對變量進行賦值。下面是一個例子&#xff1a; con…

爬蟲數據存儲:Redis、MySQL 與 MongoDB 的對比與實踐

爬蟲的核心任務是從網絡中提取數據&#xff0c;而存儲這些數據是流程中不可或缺的一環。根據業務需求的不同&#xff0c;存儲的選擇可能直接影響數據處理的效率和開發體驗。本文將介紹三種常用的存儲工具——Redis、MySQL 和 MongoDB&#xff0c;分析它們的特點&#xff0c;并提…