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.mzph.cn/web/64287.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

10分钟掌握项目管理核心工具:WBS、甘特图、关键路径法全解析

一、引言 在项目管理的广阔天地里,犹如一场精心编排的交响乐演奏,每个乐器、每个音符都需精准配合才能奏响美妙乐章。而 WBS(工作分解结构)、甘特图、关键路径法无疑是这场交响乐中的关键乐章,它们从不同维度为项目管…

代码思想之快慢路径

处理业务代码的过程中,对业务代码有了一些调整,后续发现这是一种代码思想 在一段复杂的逻辑里,我把查询redis操作写在了前面, 业务逻辑: 如果需要不打压就退出本次处理 查询redis拿到商品需要打压的次数 如果次数 …

纯 HTML+CSS+JS 实现一个炫酷的圣诞树动画特效

纯 HTMLCSSJS 实现一个炫酷的圣诞树动画特效 前言 圣诞节快到了,今天给大家带来一个简单但是效果不错的圣诞树动画特效。这个特效完全使用原生 HTML、CSS 和 JavaScript 实现,包含闪烁的星星、随机彩灯等元素,非常适合节日气氛!…

【RAG实战】语言模型基础

语言模型赋予了计算机理解和生成人类语言的能力。它结合了统计学原理和深度神经网络技术,通过对大量的样本数据进行复杂的概率分布分析来学习语言结构的内在模式和相关性。具体地,语言模型可根据上下文中已出现的词序列,使用概率推断来预测接…

富芮坤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…

python 渗透开发工具之SQLMapApi Server不同IP服务启动方式处理 解决方案SqlMapApiServer外网不能访问的情况

目录 说在前面 什么是 SQLMapAPI 说明 sqlmapApi能干什么 sqlmapApi 服务安装相关 kali-sqlmap存放位置 正常启动sqlmap-api server SqlMapApi-Server 解决外网不能访问情况 说在前面 什么是sqlmap 这个在前面已经说过了&#xff0c;如果这个不知道&#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…

【Python】使用匿名函数Lambda解析html源码的任意元素(Seleinium ,BeautifulSoup皆适用)

一直都发现lambda函数非常好用&#xff0c;它可以用简洁的方式编写小函数&#xff0c;无需写冗长的过程就可以获取结果。干脆利落&#xff01; 它允许我们定义一个匿名函数&#xff0c;在调用一次性的函数时非常有用。 最近整理了一些&#xff0c;lambda函数结合BeautifulSou…

互联网路由架构

大家觉得有意义和帮助记得及时关注和点赞!!! 本书致力于解决实际问题&#xff0c;书中包含大量的架构图、拓扑图和真实场景示例&#xff0c;内容全面 且易于上手&#xff0c;是不可多得的良心之作。本书目的是使读者成为将自有网络集成到全球互联网 领域的专家。 以下是笔记内…

【Flutter_Web】Flutter编译Web第三篇(网络请求篇):dio如何改造方法,变成web之后数据如何处理

前言 Flutter端在处理网络请求的时候&#xff0c;最常用的库当然是Dio了&#xff0c;那么在改造成web端的时候&#xff0c;最先处理的必然是网络请求&#xff0c;否则没有数据去处理驱动实图渲染。 官方链接 pub https://pub.dev/packages/diogithub https://github.com/c…

项目上传到gitcode

首先需要在个人设置里面找到令牌 记住自己的账号和访问令牌&#xff08;一长串&#xff09;&#xff0c;后面git要输入这个&#xff0c; 账号是下面这个 来到自己的仓库 #查看远程仓库&#xff0c;是不是自己的云仓库 git remote -v # 创建新分支 git checkout -b llf # 三步…

【Git学习】windows系统下git init后没有看到生成的.git文件夹

[问题] git init 命令后看不到.git文件夹 [原因] 文件夹设置隐藏 [解决办法] Win11 win10

vscode添加全局宏定义

利用vscode编辑代码时&#xff0c;设置了禁用非活动区域着色后&#xff0c;在一些编译脚本中配置的宏又识别不了 遇到#ifdef包住的代码就会变暗色&#xff0c;想查看代码不是很方便。如下图&#xff1a; 一 解决&#xff1a; 在vscode中添加全局宏定义。 二 步骤&#xff1a…

数字后端培训项目Floorplan常见问题系列专题续集1

今天继续给大家分享下数字IC后端设计实现floorplan阶段常见问题系列专题。这些问题都是来自于咱们社区IC后端训练营学员提问的问题库。目前这部分问题库已经积累了4年了&#xff0c;后面会陆续分享这方面的问题。 希望对大家的数字后端学习和工作有所帮助。 数字后端项目Floor…

【递归,搜索与回溯算法 综合练习】深入理解暴搜决策树:递归,搜索与回溯算法综合小专题(二)

优美的排列 题目解析 算法原理 解法 &#xff1a;暴搜 决策树 红色剪枝&#xff1a;用于剪去该节点的值在对应分支中&#xff0c;已经被使用的情况&#xff0c;可以定义一个 check[ ] 紫色剪枝&#xff1a;perm[i] 不能够被 i 整除&#xff0c;i 不能够被 per…

视频会议是如何实现屏幕标注功能的?

现在主流的视频会议软件都有屏幕标注功能&#xff0c;屏幕标注功能给屏幕分享者讲解分享内容时提供了极大的方便。那我们以傲瑞视频会议&#xff08;OrayMeeting&#xff09;为例&#xff0c;来讲解屏幕标注是如何实现的。 傲瑞会议的PC端&#xff08;Windows、信创Linux、银河…

改进爬山算法之四:概率爬山法(Probabilistic Hill Climbing,PHC)

概率爬山法(Probabilistic Hill Climbing,PHC)是一种局部搜索算法,它结合了随机性和贪婪搜索的特点,是对爬山算法(Hill Climbing Algorithm)的一种变体或扩展。与传统的爬山法不同,PHC不是总是选择最优的邻居作为下一步的移动,而是以一定的概率选择最优邻居,同时以一…