分布式锁之基于mysql实现分布式锁(四)

news2024/11/16 11:37:44

        不管是jvm锁还是mysql锁,为了保证线程的并发安全,都提供了悲观独占排他锁。所以独占排他也是分布式锁的基本要求。

可以利用唯一键索引不能重复插入的特点实现。设计表如下:

CREATE TABLE `tb_lock` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `lock_name` varchar(50) NOT NULL COMMENT '锁名',
  `class_name` varchar(100) DEFAULT NULL COMMENT '类名',
  `method_name` varchar(50) DEFAULT NULL COMMENT '方法名',
  `server_name` varchar(50) DEFAULT NULL COMMENT '服务器ip',
  `thread_name` varchar(50) DEFAULT NULL COMMENT '线程名',
  `create_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '获取锁时间',
  `desc` varchar(100) DEFAULT NULL COMMENT '描述',
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_unique` (`lock_name`)
) ENGINE=InnoDB AUTO_INCREMENT=1332899824461455363 DEFAULT CHARSET=utf8;

Lock实体类:

@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("tb_lock")
public class Lock {

    private Long id;
    private String lockName;
    private String className;
    private String methodName;
    private String serverName;
    private String threadName;
    private Date createTime;
    private String desc;
}

LockMapper接口:

public interface LockMapper extends BaseMapper<Lock> {
}

4.1. 基本思路

        synchronized关键字和ReetrantLock锁都是独占排他锁,即多个线程争抢一个资源时,同一时刻只有一个线程可以抢占该资源,其他线程只能阻塞等待,直到占有资源的线程释放该资源。

  1. 线程同时获取锁(insert)

  2. 获取成功,执行业务逻辑,执行完成释放锁(delete)

  3. 其他线程等待重试

4.2. 代码实现

改造StockService:

@Service
public class StockService {

    @Autowired
    private StockMapper stockMapper;

    @Autowired
    private LockMapper lockMapper;

    /**
     * 数据库分布式锁
     */
    public void checkAndLock() {

        // 加锁
        Lock lock = new Lock(null, "lock", this.getClass().getName(), new Date(), null);
        try {
            this.lockMapper.insert(lock);
        } catch (Exception ex) {
            // 获取锁失败,则重试
            try {
                Thread.sleep(50);
                this.checkAndLock();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

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

        // 再减库存
        if (stock != null && stock.getCount() > 0){

            stock.setCount(stock.getCount() - 1);
            this.stockMapper.updateById(stock);
        }

        // 释放锁
        this.lockMapper.deleteById(lock.getId());
    }
}

加锁:

// 加锁
Lock lock = new Lock(null, "lock", this.getClass().getName(), new Date(), null);
try {
    this.lockMapper.insert(lock);
} catch (Exception ex) {
    // 获取锁失败,则重试
    try {
        Thread.sleep(50);
        this.checkAndLock();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

解锁:

// 释放锁
this.lockMapper.deleteById(lock.getId());

使用Jmeter压力测试结果:

可以看到性能感人。mysql数据库库存余量为0,可以保证线程安全。

4.3. 缺陷及解决方案

缺点

  1. 这把锁强依赖数据库的可用性,数据库是一个单点,一旦数据库挂掉,会导致业务系统不可用。

    解决方案:给 锁数据库 搭建主备

  2. 这把锁没有失效时间,一旦解锁操作失败,就会导致锁记录一直在数据库中,其他线程无法再获得到锁。

    解决方案:只要做一个定时任务,每隔一定时间把数据库中的超时数据清理一遍。

  3. 这把锁是非重入的,同一个线程在没有释放锁之前无法再次获得该锁。因为数据中数据已经存在了。

    解决方案:记录获取锁的主机信息和线程信息,如果相同线程要获取锁,直接重入。

  4. 受制于数据库性能,并发能力有限。

    解决方案:无法解决。

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

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

相关文章

最小二乘线性回归

​ 线性回归&#xff08;linear regression&#xff09;&#xff1a;试图学得一个线性模型以尽可能准确地预测实际值的输出。 以一个例子来说明线性回归&#xff0c;假设银行贷款会根据 年龄 和 工资 来评估可放款的额度。即&#xff1a; ​ 数据&#xff1a;工资和年龄&…

企业必看的大数据安全极速传输解决方案

在这个大数据时代&#xff0c;企业在享受大数据带来的便利同时&#xff0c;也面临着巨大的挑战&#xff0c;其中最主要的问题就是数据安全方面和传输方面&#xff0c;为了更好地满足企业大数据传输的需求&#xff0c;小编将深入分析企业对于大数据传输面临的挑战和风险以及大数…

[PTQ]均匀量化和非均匀量化

均匀量化和非均匀量化 基本概念 量化出发点&#xff1a;使用整型数据类型代替浮点数据&#xff0c;从而节省存储空间同时加快推理速度。量化基本形式 均匀量化&#xff1a;浮点线性映射到定点整型上&#xff0c;可以根据scale/offset完成量化/反量化操作。非均匀量化 PowersO…

containerd Snapshots功能解析

containerd Snapshots功能解析 snapshot是containerd的一个核心功能&#xff0c;用于创建和管理容器的文件系统。 本篇containerd版本为v1.7.9。 本文以 ctr i pull命令为例&#xff0c;分析containerd的snapshot “创建” 相关的功能。 ctr命令 ctr image相关命令的实现在cmd…

OpenAI“宫斗”新进展!Sam Altman将重返OpenAI担任首席执行官 董事会成员改动

在经过激烈的五天讨论和辩论之后&#xff0c;高调人工智能初创公司OpenAI宣布&#xff0c;其联合创始人之一Sam Altman将回归担任首席执行官。这一决定是对上周Altman突然被解雇的回应&#xff0c;该决定引起了极大的关注和讨论。 OpenAI表示&#xff0c;他们已经达成了与Altm…

低代码平台推荐:五大低代码厂商谁的模式更“合适”

随着数字化时代的到来&#xff0c;低代码开发平台作为提高数字生产力的工具正受到越来越多企业的关注&#xff0c;市面上的低代码产品和厂商更是“乱花渐欲迷人眼”。 各家产品不仅功能各有不同&#xff0c;甚至商机都有区别的情况&#xff0c;如何做好产品选型已然成了采购企…

2023年国内好用的企业网盘推荐

2023年企业网盘俨然已经成为了各个企业团队的标配了&#xff0c;那么2023年国内有什么好用的企业网盘吗&#xff1f;2023国内哪个企业网盘好用&#xff1f; 国内哪个企业网盘好用&#xff1f; 由于不同行业企业对于企业网盘的具体需求点不同&#xff0c;因此我们无法从功能上评…

idea 2023 安装配置 Gradle8.4

官网&#xff1a;https://gradle.org 下载 Gradle8.4 https://gradle.org/releases/ 解压到本地&#xff0c;到 gradle-8.4\init.d 目录下新建文件&#xff1a;init.gradle 这里有个坑&#xff0c;编译报http协议安全的问题&#xff0c;解决办法&#xff0c;加入&#xff1…

【EI会议征稿】第十一届先进制造技术与材料工程国际学术会议 (AMTME 2024)

JPCS独立出版/高录用快检索/院士杰青云集 第十一届先进制造技术与材料工程国际学术会议 (AMTME 2024) 2024 11th International Conference on Advanced Manufacturing Technology and Materials Engineering 第十一届先进制造技术与材料工程国际学术会议 (AMTME 2024) 定于…

前端处理返回数据为数组对象且对象嵌套数组并重名的数据,合并名称并叠加数据

前端处理返回数据为数组对象且对象嵌套数组并重名的数据&#xff0c;合并名称并叠加数据 var newList[]; var table{}; var dataObj{}; var finalList[]; var tableData[{brName:营业部,dateStr:2023-11-23,tacheArr:[{dealCnt:20,tacheName:奔驰}]},{brName:营业部,dateStr:2…

软件开发团队如何确保团队成员与项目进度一致?

在软件开发团队中&#xff0c;确保团队成员的利益与项目进度保持一致&#xff0c;可以采取以下措施&#xff1a; 建立基础流程&#xff1a;建立几个最主要的流程&#xff0c;如任务跟踪、开发效率提升、任务完成等&#xff0c;可以帮助小团队从无序逐步进入有序。 关注员工反馈…

【逆向】NahamCon CTF -Click Me Writeup(BridaFrida Hook 拿Flag)

文章目录 前言一、样式与功能点二、反编译三、Frida Get Flag四、BurpSuite插件-Brida总结 前言 第一次做外国CTF比赛的mobile challenge 题&#xff0c;题目就是一个安卓的apk安装包。顺便记录一下代码分析过程以及分享两种不同的解题思路。 提示&#xff1a;以下是本篇文章正…

选对软件公司,助力小程序商城腾飞

选择一家合适的软件公司对于小程序商城的开发和运营至关重要。在众多的软件公司中&#xff0c;如何找到最适合自己的合作伙伴呢&#xff1f;本文将从实际需求、公司实力、案例展示、服务态度和价格等五个方面&#xff0c;为您解析如何选择合适的软件公司。 一、明确实际需求 在…

用「超舒适」突围,星纪元 ES 加量不加价

在 2023 广州车展上&#xff0c;星途星纪元 ES 正式开启预售&#xff0c;新车预售区间 24.8-35.8 万元&#xff0c;共推出五款车型配置。 外观方面&#xff0c;星纪元 ES 前脸采用了封闭式的设计&#xff0c;前大灯组采用了流行的贯穿式设计搭配矩阵大灯&#xff0c;使得整个灯…

cefsharp119.4.30(cef119.4.3Chromium119.0.6045.159)版本升级体验支持x86_h264及其他多个h264版本

Cefsharp119.4.30,cef119.4.3,Chromium119.0.6045.159 此更新包括一个高优先级安全更新 This update includes a high priority security update. 说明:此版本119.4.3支持x86_H264视频播放(需要联系我),其他版本。.NETFramework 4.6.2 NuGet Gallery | CefSharp.WinForms …

Selenium(12):层级定位_通过父元素找到子元素

层级定位 在实际的项目测试中&#xff0c;经常会遇到无法直接定位到需要选取的元素&#xff0c;但是其父元素比较容易定位&#xff0c;通过定位父元素再遍历其子元素选择需要的目标元素&#xff0c;或者需要定位某个元素下所有的子元素。 层级定位的思想是先定位父对象&#xf…

外包干了4年,技术算是没了...

先说一下自己的情况。大专生&#xff0c;19年通过校招进入湖南某软件公司&#xff0c;干了接近3年的测试&#xff0c;今年年上旬&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落&#xff01;而我已经在一个企业干了三年&#xff0c…

企业邮箱即时提醒服务推荐

现在用企业邮箱比较多&#xff0c;但是不能即时提醒&#xff0c;总是误事&#xff0c;什么邮箱可以即时提醒呢&#xff1f;随着工作和生活节奏的加快&#xff0c;传统的电子邮件系统由于不能即时提醒&#xff0c;往往会导致重要邮件的漏接&#xff0c;从而引发一系列的麻烦和误…

java--继承快速入门

1.什么是继承 java中提供了一个关键字extends&#xff0c;用这个关键字&#xff0c;可以让一个类和另一个类建立其父子关系。 2.继承的特点 子类能继承父类的非私有成员(成员变量&#xff0c;成员方法)。 3.继承后对象的创建 子类的对象是由子类、父类共同完成的。 4.继承的…