乐观锁

news/2025/1/4 21:11:52/文章来源:https://www.cnblogs.com/zyb-luckey/p/18648631

业务场景:商品库存更新

1. 数据库表设计

我们在商品表 Product 中添加一个 version 字段,用来实现乐观锁。每当库存更新时,都会检查并更新该字段的值。

sql
CREATE TABLE product ( id BIGINT PRIMARY KEY, name VARCHAR(255), stock INT, version INT DEFAULT 1 -- 版本号字段,用来实现乐观锁 );

2. 实体类设计

在实体类中,通过 MyBatis-Plus 的 @Version 注解来标记 version 字段。

java
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.Version; @TableName("product") public class Product { private Long id; private String name; private Integer stock; @Version // 使用 MyBatis-Plus 的乐观锁注解 @TableField("version") // 映射数据库中的 version 字段 private Integer version; // Getter 和 Setter }

3. 乐观锁更新库存操作

当用户进行购买时,我们首先查询商品库存,然后尝试更新库存。如果更新时发现版本号发生变化,说明该商品的库存已经被其他用户修改过,我们就会拒绝这次操作。

java
public class ProductService { @Autowired private ProductMapper productMapper; public boolean purchase(Long productId, int quantity) { // 1. 查询商品信息 Product product = productMapper.selectById(productId); if (product == null || product.getStock() < quantity) { // 商品不存在或库存不足,购买失败 return false; } // 2. 扣减库存 product.setStock(product.getStock() - quantity); // 3. 使用乐观锁更新商品库存,version 字段自动处理 int updatedRows = productMapper.updateById(product); // 如果返回的更新行数为 0,说明版本号不一致,库存已经被其他用户修改 if (updatedRows == 0) { // 更新失败,可能因为并发冲突 return false; } return true; } }

4. 乐观锁执行过程

假设商品的 id = 1,初始库存为 10,版本号为 1。

  • 用户 A

    • 查询库存:库存为 10,版本号为 1。
    • 扣减库存:购买 5 个,库存剩余 5,版本号自增为 2。
    • 执行 updateById,更新成功,库存变为 5,版本号变为 2。
  • 用户 B

    • 查询库存:库存为 10,版本号为 1。
    • 扣减库存:购买 5 个,库存剩余 5,版本号自增为 2。
    • 执行 updateById但此时商品的版本号已经被用户 A 更新为 2
    • 用户 B 的更新操作失败,updateById 返回更新行数为 0,库存没有被更新。

5. SQL 生成过程

在执行 updateById 时,MyBatis-Plus 会自动生成类似如下的 SQL:

sql
UPDATE product SET stock = stock - 5, version = version + 1 WHERE id = 1 AND version = 1;
  • 如果 version = 1,更新操作会成功,库存减少 5,version 增加到 2。
  • 如果 version 已经不是 1,说明其他用户已经更新了该记录,更新操作将失败,返回 0 行更新。

6. 乐观锁的优势:

  • 减少锁竞争:与悲观锁不同,乐观锁不需要在更新时对数据进行加锁,适用于读多写少的场景,能够提高系统的并发性能。
  • 避免死锁:乐观锁没有锁竞争,因此避免了死锁的发生。
  • 业务简洁:只需在实体类中标注 @Version,MyBatis-Plus 会自动处理版本号的增减。

7. 乐观锁的不足:

  • 冲突时可能会丢失更新:当多个用户几乎同时操作相同数据时,可能会因为版本号不一致导致更新失败,需要在业务逻辑中捕获异常并做重试或其他处理。
  • 适用场景有限:乐观锁适用于冲突概率低的场景,冲突频繁时,可能反而导致频繁的更新失败,效率低下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/863049.html

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

相关文章

显卡危机的解决方案,全面解析ToDesk云电脑:服务配置与应用场景探索

ToDesk云电脑是一款集成了高性能计算资源的云端服务,旨在为用户提供便捷、高效、安全的计算体验。无论是游戏玩家、设计师还是企业用户,都能通过ToDesk云电脑享受到强大的计算能力和灵活的资源配置。ToDesk云电脑以其强大的性能、灵活的服务和优质的用户体验,正在迅速赢得市…

【有源码】周边旅游平台系统+SpringBoot+VUE+前后端分离

学弟,学妹好,我是爱学习的学姐,今天带来一款优秀的项目:流浪宠物管理系统。 本文介绍了系统功能与部署安装步骤,如果您有任何问题,也请联系学姐,偶现在是经验丰富的程序员! 一. 系统演示 管理后台-截图前端-截图 视频演示 https://githubs.xyz/show/327.mp4二. 系统概述…

01java反序列化基础

java反射的相关操作 一些重要的方法获取类的⽅法: forName实例化类对象的⽅法: newInstance获取函数的⽅法: getMethod执⾏函数的⽅法: invoke// eg.反射获取任意类的任意方法并执行 import java.lang.reflect.Method;public class ReflectionExample {public static void …

单元化架构最佳实践指南!

0 前言单元化架构通过减少故障影响范围来增强系统的弹性。 单元化架构是对于那些无法接受停机或可能对最终用户产生负面影响的系统的良好选择。 单元化架构可能很复杂,有一些最佳实践可以遵循,以提高成功的机会。 在推出单元化架构或将现有的云原生/微服务架构改造/转变为单元…

苹果鼠标有望加入 AI 语音控制功能;Accent Oracl :准确识别你口音的 AI 丨 RTE 开发者日报

开发者朋友们大家好:这里是 「RTE 开发者日报」 ,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE(Real-Time Engagement) 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文章 」、「有看点的 会议 」,但内容仅代表编辑…

计算机网络复习应用层(第六章)

应用层 应用层的共同特点:C/S或者P2P、推/拉、面向文本/面向二进制域名系统(DNS) 名字到IP地址的解析互联网的域名空间 互联网采用了层次树状结构的命名方式采用:.四级域名.三级域名.二级域名.顶级域名 其中本地域名服务器向根域名服务器发出DNS请求,根域名服务器进行查找…

【有源码】流浪宠物管理系统+SpringBoot+VUE+前后端分离

学弟,学妹好,我是爱学习的学姐,今天带来一款优秀的项目:流浪宠物管理系统。 本文介绍了系统功能与部署安装步骤,如果您有任何问题,也请联系学姐,偶现在是经验丰富的程序员! 一. 系统演示 管理后台-截图前端-截图视频演示 https://githubs.xyz/show/326.mp4二. 系统概述…

.Net Core 管道底层源码实现

在 .NET Core 中,请求处理管道是一个中间件(Middleware)链,用于处理 HTTP 请求并生成响应。管道的底层实现基于 Microsoft.AspNetCore.Http 命名空间中的一些核心类和接口1. 核心组件 1.1 HttpContext• HttpContext 是 HTTP 请求和响应的核心抽象,封装了请求信息(如请求…

JavaScript代码安全性提升:选择和使用JS混淆工具的指南

https://toolin.cn/jsfuckhttps://maimai.cn/article/detail?fid=1827257627&efid=382Pa05uQ_i7jAl6rmq5tg在Web开发中,JavaScript是一种常用的脚本语言,然而,由于其代码容易被他人轻易获取和修改,为了保护JavaScript代码的安全性和版权,我们需要使用JS混淆工具。本文…

AI 驱动研发模式升级,蓝凌软件探索效率提升之道

蓝凌软件在引入通义灵码后取得了较明显的效果。目前,蓝凌软件已使用灵码的开发人员中,周活跃用户占比超过90%、根据代码库自动生成的代码占比超33%、代码智能补全占比29%,代码注释率提升了15%,有效提升了产品代码工程化的效能。深圳市蓝凌软件股份有限公司(以下简称蓝凌软…

“越用越上瘾”,中华财险 60% 研发人员用通义灵码提效

保险业被看成是社会“稳定器”和经济“助推器”,近年来已驶入数字化发展快车道。在 AI、大模型当道的今天,保险行业的研发流程、产品设计、场景拓展等业务链条各环节,都值得用大模型进行重塑。保险业被看成是社会“稳定器”和经济“助推器”,近年来已驶入数字化发展快车道。…