分布式锁之mysql 锁

news2024/11/8 6:50:31

文章目录

  • 使用数据锁:悲观锁 或者 乐观锁
    • 悲观锁
    • 乐观锁
    • mysql锁总结

使用数据锁:悲观锁 或者 乐观锁

  1. 一个sql:直接更新时判断,在更新中判断库存是否大于0

    update table set surplus = (surplus - buyQuantity) where id = 1 and (surplus - buyQuantity) > 0 ;

  2. 悲观锁:在读取数据时锁住那几行,其他对这几行的更新需要等到悲观锁结束时才能继续 。

    select … for update

  3. 乐观锁:读取数据时不锁,更新时检查是否数据已经被更新过,如果是则取消当前更新进行重试。

    version 或者 时间戳(CAS思想)。

悲观锁

在MySQL的InnoDB中,预设的Tansaction isolation level 为REPEATABLE READ(可重读)
在SELECT 的读取锁定主要分为两种方式:

  • SELECT … LOCK IN SHARE MODE (共享锁)
  • SELECT … FOR UPDATE (悲观锁)
  • 这两种方式在事务(Transaction) 进行当中SELECT 到同一个数据表时,都必须等待其它事务数据被提交(Commit)后才会执行。
  • 而主要的不同在于LOCK IN SHARE MODE 在有一方事务要Update 同一个表单时很容易造成死锁。
  • 简单的说,如果SELECT 后面若要UPDATE 同一个表单,最好使用SELECT … FOR UPDATE。

代码实现

改造StockService:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在StockeMapper中定义selectStockForUpdate方法:

public interface StockMapper extends BaseMapper<Stock> {

    public Stock selectStockForUpdate(Long id);
}

在StockMapper.xml中定义对应的配置:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.distributedlock.mapper.StockMapper">

    <select id="selectStockForUpdate" resultType="com.atguigu.distributedlock.pojo.Stock">
        select * from db_stock where id = #{id} for update
    </select>
</mapper>

压力测试

注意:测试之前,需要把库存量改成5000。压测数据如下:比jvm性能高很多,比无锁要低将近1倍
在这里插入图片描述

mysql数据库存:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

乐观锁

乐观锁( Optimistic Locking ) 相对悲观锁而言,乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则重试。那么我们如何实现乐观锁呢

使用数据版本(Version)记录机制实现,这是乐观锁最常用的实现 方式。一般是通过为数据库表增加一个数字类型的 “version” 字段来实现。当读取数据时,将version字段的值一同读出,数据每更新一次,对此version值加一。当我们提交更新的时候,判断数据库表对应记录 的当前版本信息与第一次取出来的version值进行比对,如果数据库表当前版本号与第一次取出来的version值相等,则予以更新。

给db_stock表添加version字段:

在这里插入图片描述

对应也需要给Stock实体类添加version属性。此处略。。。。

代码实现

public void checkAndLock() {

    // 先查询库存是否充足
    Stock stock = this.stockMapper.selectById(1L);

    // 再减库存
    if (stock != null && stock.getCount() > 0){
        // 获取版本号
        Long version = stock.getVersion();

        stock.setCount(stock.getCount() - 1);
        // 每次更新 版本号 + 1
        stock.setVersion(stock.getVersion() + 1);
        // 更新之前先判断是否是之前查询的那个版本,如果不是重试
        if (this.stockMapper.update(stock, new UpdateWrapper<Stock>().eq("id", stock.getId()).eq("version", version)) == 0) {
            checkAndLock();
        }
    }
}

重启后使用jmeter压力测试工具结果如下:

在这里插入图片描述

修改测试参数如下:

在这里插入图片描述

测试结果如下:

在这里插入图片描述

说明乐观锁在并发量越大的情况下,性能越低(因为需要大量的重试);并发量越小,性能越高。

mysql锁总结

性能:一个sql > 悲观锁 > jvm锁 > 乐观锁

如果追求极致性能、业务场景简单并且不需要记录数据前后变化的情况下。

​ 优先选择:一个sql

如果写并发量较低(多读),争抢不是很激烈的情况下优先选择:乐观锁

如果写并发量较高,一般会经常冲突,此时选择乐观锁的话,会导致业务代码不间断的重试。

​ 优先选择:mysql悲观锁

不推荐jvm本地锁。

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

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

相关文章

Occupancy占据网络论文讲解与分析

一.MonoScene 1.概要 a.使用单目相机&#xff0c;不用深度估计和点云来实现占据网络。 b.提出了一种2D-3D的一种转换方法。 c.在3D-unet底部加入3DCRP来捕获长距离的一个信息。 2.模型结构 图像先经过一个2D的unet结构&#xff0c;这里论文里用的预训练的EfficientNet&am…

I350网卡烧录oprom,通过UEFI PXE引导方案

Intel发布的I350标准固件都是用于LOM设计的。固件已配置LOM模式&#xff0c;不需要搭配外挂flash&#xff0c;将efi driver包进BIOS中就可以使用PXE功能&#xff0c;因此NIC类型的时候直接烧录oprom会报错。 如使用外部flash存放PXE ROM&#xff0c;需要将固件修改为NIC的配置…

蓝桥杯(砝码称重,C++)

思路&#xff1a; 1、用到动态规划思想。 2、用ans[i][j]记录用前i个砝码&#xff0c;能不能称出重量j。 3、详细思路见代码注释&#xff0c;易懂。 #include<iostream> #include<cmath> using namespace std; int main() {int n;int a[110];//记录每个砝码重量int…

8+非肿瘤+线粒体+实验生信思路解析

今天给同学们分享一篇非肿瘤线粒体实验的生信文章“Role of mitochondrial metabolic disorder and immune infiltration in diabetic cardiomyopathy: new insights from bioinformatics analysis”&#xff0c;这篇文章于2023年2月1日发表在J Transl Med期刊上&#xff0c;影…

EPLAN_004#常用功能(四)

线号&#xff1a;火线L&#xff0c;零线N&#xff0c;正极P&#xff0c;负极是M 一、基于设备的设计 也可以通过下面的&#xff08;设备选择&#xff09;进行选择 如果是批量选型&#xff0c;可以在设备导航器中进行多个相同元器件进行选型。&#xff08;筛选器可以自定义&…

前端使用qrcodejs2插件实现根据网址生成二维码

实现效果&#xff1a; 实现方法&#xff1a; 1.安装插件 npm install --save qrcodejs2 2.可以全局引入&#xff0c;也可以只在使用的vue文件中引入 import QRCode from qrcodejs2; 3.在vue文件的template中设置放置二维码的div <div id"qrcode"></di…

8个视频剪辑素材网站,免费下载

找视频剪辑素材就上这8个网站&#xff0c;免费下载&#xff0c;可商用&#xff0c;赶紧收藏起来~ 免费视频素材 1、菜鸟图库 https://www.sucai999.com/video.html?vNTYxMjky 菜鸟图库网素材非常丰富&#xff0c;网站主要还是以设计类素材为主&#xff0c;高清视频素材也很多…

ssm+vue的毕业生跟踪调查反馈管理系统(有报告)。Javaee项目,ssm vue前后端分离项目。

演示视频&#xff1a; ssmvue的毕业生跟踪调查反馈管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;ssm vue前后端分离项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层…

整理uvc驱动相关函数的调用流程

目录 1、uvc_video.c初始化函数的调用关系 2、uvc_queue.c3、uvc_v4l2.c4、v4l2-core5、数据传输1、分配一个gadget请求2、请求一个queue 1、uvc_video.c // uvc_video.c uvc_video_encode_header uvc_video_encode_data uvc_video_encode_bulk uvc_video_encode_isoc uvcg_vi…

Python学习基础笔记七十八——Socket编程1

现在的软件开发基本上都需要网络通讯。 不管是传统计算机软件&#xff0c;还是手机软件&#xff0c;还是物联网嵌入系统软件&#xff0c;这些都要和其他网络系统进行通讯。 而当今世界基本上都是使用TCP/IP协议进行通讯的。 TCP/IP协议是一种传输数据的方案。 收发信息的程序…

每个epoch的溯源(MNE)

每个epoch的溯源&#xff1a; from mne.minimum_norm import apply_inverse_epochs stcs apply_inverse_epochs(epochs,inverse_operator,lambda2,method,pick_ori"normal"# naveevoked.nave, )

ArrayDeque 源码解析(JDK1.8)

目录 一. 前言 二. 源码解析 2.1. 概览 2.2. 属性 2.3. 构造方法 2.4. 入队 2.4.1. addFirst(E, e) 2.4.2. add(E e) & addLast(E e) 2.4.3. offer(E e) 2.5. 扩容 2.6. 出队 2.6.1. poll() & pollFirst() 2.6.2. pollLast() 2.7. 删除元素 2.8. 获取元…

springweb+vue前后端分离开发,集成部署

背景&#xff1a; 在自己做测试的时候&#xff0c;由于需要项目和项目的前端页面使用同样接口访问&#xff0c;所以需要将前端代码部署到后端项目下。前端采用vue&#xff0c;后端采用springboot。 首先时建立一个vue项目&#xff0c;这个可以参照网上的案例&#xff0c;创建方…

思维模型 巴纳姆效应

本系列文章 主要是 分享 思维模型&#xff0c;涉及各个领域&#xff0c;重在提升认知。 1 巴纳姆效应的应用 1.1 “占卜者”的故事 1 遇到占卜师的汤姆 汤姆是一位年轻的上班族&#xff0c;他一直对自己的未来感到迷茫和困惑。有一天&#xff0c;他在一家神秘的占卜店里遇到…

Python处理PDF——PyMuPDF的安装与使用详解

​​​​​​​ 1、PyMuPDF简介 1. 介绍 在介绍PyMuPDF之前&#xff0c;先来了解一下MuPDF&#xff0c;从命名形式中就可以看出&#xff0c;PyMuPDF是MuPDF的Python接口形式。 MuPDF MuPDF 是一个轻量级的 PDF、XPS和电子书查看器。MuPDF 由软件库、命令行工具和各种…

28 mysql 数据记录的 存储更新删除

前言 前面 我们探讨了 索引记录的 新增, 更新, 删除 这里 我们来看一下 mysql 的核心数据记录的 新增更新删除 这里 来看一下 增删改 的相关实现 数据记录 和 索引记录 的处理方式是一致的 mysql 数据记录的存储 新增部分参见 自增长主键的实现 以及 记录的插入 mysql…

解决提交到App Store时的ITMS-90478和ITMS-90062错误

目录 引言 正文 1. 什么是ITMS-90478和ITMS-90062错误&#xff1f; 2. 解决方法 2.1 确定当前的版本号和构建号 2.2 递增版本号和构建号 2.3 再次尝试提交应用 总结 参考资料 错误记录 摘要&#xff1a;本文为iOS技术博主分享&#xff0c;将详细介绍解决提交应用到App…

QCustomPlot添加标题头

1 效果图 2 代码 is2Label QString("add title layout element");// add title layout element:ui->customplot->plotLayout()->insertRow(0);ui->customplot->plotLayout()->addElement(0, 0, new QCPTextElement(ui->customplot, xAxis2Lab…

设备巡检管理系统有什么用?企业如何提高生产效率和生产安全?

在当今工业生产领域&#xff0c;设备巡检的重要性不言而喻。然而&#xff0c;传统巡检方式存在的诸多问题&#xff0c;如数据不规范、漏检误检等&#xff0c;严重制约了企业生产效率和产品质量。为解决这一问题&#xff0c;我们推出了一款设备巡检管理系统——“的修”工单管理…

宝塔Nginx配置反向代理后如何配置跨域?

直接将 27行更换成如下配置即可 上图有示例 if ( $static_fileAUWz2fmi 0 ){add_header Cache-Control no-cache;add_header Access-Control-Allow-Origin "$http_origin";add_header Access-Control-Allow-Methods GET, POST, PUT, DELETE, OPTIONS;add_header Acc…