性能优化——设计更优的分布式锁?

2023-11-20

那什么是分布式锁呢,它又是用来解决哪些问题的呢?
 
在 JVM 中,在多线程并发的情况下,我们可以使用同步锁或 Lock 锁,保证在同一时间内,只能有一个线程修改共享变量或执行代码块。但现在我们的服务基本都是基于分布式集群来实现部署的,对于一些共享资源,例如我们之前讨论过的库存,在分布式环境下使用 Java 锁的方式就失去作用了。
 
这时,我们就需要实现分布式锁来保证共享资源的原子性。除此之外,分布式锁也经常用来避免分布式中的不同节点执行重复性的工作,例如一个定时发短信的任务,在分布式集群中,我们只需要保证一个服务节点发送短信即可,一定要避免多个节点重复发送短信给同一个用户。
 
因为数据库实现一个分布式锁比较简单易懂,直接基于数据库实现就行了,不需要再引入第三方中间件,所以这是很多分布式业务实现分布式锁的首选。但是数据库实现的分布式锁在一定程度上,存在性能瓶颈。
 
接下来我们一起了解下如何使用数据库实现分布式锁,其性能瓶颈到底在哪,有没有其它实现方式可以优化分布式锁。
 
数据库实现分布式锁
 
首先,我们应该创建一个锁表,通过创建和查询数据来保证一个数据的原子性:
 
CREATE TABLE `order` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`order_no` int(11) DEFAULT NULL,
`pay_money` decimal(10, 2) DEFAULT NULL,
`status` int(4) DEFAULT NULL,
`create_date` datetime(0) DEFAULT NULL,
`delete_flag` int(4) DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_status`(`status`) USING BTREE,
INDEX `idx_order`(`order_no`) USING BTREE
) ENGINE = InnoDB
 
其次,如果是校验订单的幂等性,就要先查询该记录是否存在数据库中,查询的时候要防止幻读,如果不存在,就插入到数据库,否则,放弃操作。
 
select id from `order` where `order_no`= 'xxxx' for update
 
最后注意下,除了查询时防止幻读,我们还需要保证查询和插入是在同一个事务中,因此我们需要申明事务,具体的实现代码如下:
 
@Transactional
public int addOrderRecord(Order order) {
if(orderDao.selectOrderRecord(order)==null){
int result = orderDao.addOrderRecord(order);
if(result>0){
return 1;
}
}
return 0;
}
 
到这,我们订单幂等性校验的分布式锁就实现了
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

性能优化——设计更优的分布式锁? 的相关文章

  • 在 Java 中有效地对图像进行颜色循环

    我正在编写一个曼德尔布罗分形查看器 我想以智能的方式实现颜色循环 给定一个图像 我想修改它的 IndexColorModel 据我所知 没有办法修改 IndexColorModel 也没有办法为图像提供新的 IndexColorModel
  • 在 Spring Boot 中重新加载/刷新缓存

    我正在使用 Spring Boot 对于缓存 我使用 Ehcache 到目前为止一切正常 但现在我必须重新加载 刷新 那么我该如何执行此操作 以便我的应用程序不会出现任何停机时间 我在Spring Ehcache中尝试了很多方法 但它不起作
  • Eclipse 中的 Java 简单电子邮件程序

    我想制作一个简单的程序 您可以从其中发送电子邮件命令行 我找到了这个教程 http www tutorialspoint com java java sending email htm http www tutorialspoint com
  • SWIG 类型映射 uint8_t* 从 C/C++ 到 java.nio.ByteBuffer

    我正在尝试将输入和输出缓冲区从 C 传递给 java 类 出于效率原因 我需要使用 ByteBuffer 这两个缓冲区都是在 C 部分中分配的 我需要将它们传递给一个 java 函数 该函数将使用输入缓冲区进行一些计算并将结果写入输出缓冲区
  • 如何向 OkHttp 请求拦截器添加标头?

    我将这个拦截器添加到我的 OkHttp 客户端 public class RequestTokenInterceptor implements Interceptor Override public Response intercept C
  • SimpleDateFormat 无法正确处理 DD

    我正在尝试获得这样的格式 2013 06 15 17 45 我在代码中执行以下操作 Date d new Date SimpleDateFormat ft new SimpleDateFormat YYYY MM DD HH mm Stri
  • 从 Java 启动外部进程:stdout 和 stderr

    我正在使用标准从 java 启动一个外部进程java lang Process 我试图弄清楚该过程的输出是什么 但是采用结合了两者的格式stdout and stderr 目前 我有Process getInputStream它提供了访问s
  • Eclipse 内容协助无法在枚举常量参数列表中工作

    使用 eclipse 当我输入以下内容时 public enum Foo A Integer private final Integer integer private Foo Integer integer this integer in
  • 带有 @Scheduled Spring 注释的方法的切入点

    我想要一个带有注释的方法的 AspectJ 切入点 Scheduled 尝试了不同的方法但没有任何效果 1 Pointcut execution org springframework scheduling annotation Sched
  • Android 防火墙与 VpnService

    我正在尝试使用 BS 项目的 VpnService 为 Android 实现一个简单的防火墙 我选择 VpnService 因为它将在非 root 设备上运行 它将记录连接并让您过滤连接 基于IP 有一个应用程序可以做到这一点 因此这是可能
  • Android Google 地图:隐藏整个地图的多边形或形状

    我试图隐藏除一个区域之外的整个地图 因为我使用的多边形在我想要显示的区域中有一个洞 问题在于 根据缩放的不同 空白区域会被多边形的颜色覆盖 或者多边形会失去其颜色 这是代码 polygon hide all world map float
  • Java Swing JEditorPane:操作样式文档

    我的模型是与枚举类型关联的字符串队列 我试图在 JEditorPane 中显示该模型 队列中的每个元素作为一个单独的 HTML 段落 其属性基于关联的枚举类型 但是 我的更新方法并没有达到我想要的效果 我尝试将 HTML 字符串直接写入文档
  • 使用 Lint 和 SonarQube 分析 Android 项目

    我真的 溢出 了试图让这些东西一起工作 我按照这里的指示进行操作 http docs sonarqube org display PLUG Android Lint Plugin http docs sonarqube org displa
  • C3P0:生产中未返回的连接超时?

    参数unreturnedConnectionTimeout给定时间段后未返回的连接超时 我正在尝试决定是否应该在我的制作中使用它persistence xml 使用它的一大优点是连接池将能够从泄漏的连接中恢复 一个很大的缺点是泄漏的连接将很
  • 使用 OpenNLP 获取句子的解析树。陷入困境。

    OpenNLP 是一个关于自然语言处理的 Apache 项目 NLP 程序的目标之一是解析一个句子 并给出其语法结构的树 例如 天空是蓝色的 这句话 可能会被解析为 S NP VP The sky is blue where S是句子 NP
  • 从 IntelliJ 运行 JavaFX 应用程序

    Versions openjdk版本 11 0 11 2021 04 20 OpenJDK 运行时环境 build 11 0 11 9 Ubuntu 0ubuntu2 20 10 OpenJDK 64 位服务器虚拟机 内部版本 11 0 1
  • 如何使用 Kafka 发送大消息(超过 15MB)?

    我发送字符串消息到Kafka V 0 8使用 Java Producer API 如果消息大小约为 15 MB 我会得到MessageSizeTooLargeException 我尝试过设置message max bytes到 40 MB
  • Hibernate 命名查询使用 Like 和 % % 运算符?

    在我的 Hibernate JPA 示例代码中 public List
  • 如何获取 res.drawable 文件夹的路径来复制文件?

    我正在编写我的应用程序AndroidStudio 我的里面有gif文件drawable gifs文件夹 我希望将该文件复制到MediaStore Images Media单击按钮后的文件夹 目前 即使使用发布的一些答案 我也无法获取我的 g
  • selenium 没有找到合适的方法,直到(ExpectedCondition)

    这是有线的问题 我导入的项目运行 100 几个月前 今天我已将其与依赖项一起导入 但存在问题WebDriverWait 这是我的代码 WebDriverWait driverWait new WebDriverWait driver 100

随机推荐

  • 运行Chrome中的app

    chrome apps
  • python中and与or的计算规则

    1 在纯and语句中 如果每一个表达式都不是假的话 那么返回最后一个 因为需要一直匹配直到最后一个 如果有一个是假 那么返回假 2 在纯or语句中 只要有一个表达式不是假的话 那么就返回这个表达式的值 只有所有都是假 才返回假 3 在or和
  • git 报错did not match any file(s) known to git

    前言 在使用gitLab中时遇到一个问题 就是我在gitLab新建分支后 在本地切换分支不成功 遇到了这个问题 在大佬的博客的指点下 顺利解决这个问题 记录下我一步一步解决问题的过程 最后面是我参考大佬的地址 有兴趣的朋友可以去看一下 问题
  • 使用花生壳将自己的Linux主机配置为服务器

    1 服务端花生壳配置 http service oray com question 11630 html 如果在客户端连接失败 在这里点击诊断 如果局域网服务器连接成功才行 不成功可能的原因有两个 1 配置不对 内网主机要写Linux主机的
  • matlab产生高斯噪声

    randn randn random normal distribution 是一种产生标准 正态分布的 随机数或 矩阵的函数 属于MATLAB函数 返回一个n n的随机项的矩阵 如果n不是个数量 将返回错误信息 MATLAB函数randn
  • 编程杂感两篇

    一 Null是个巨大的错误吗 为null正名 null可以表示未初始化的引用 为什么不强迫初始化 因为初始化时可能抛异常 变量声明放进try块 又可能有跨作用域的需求 一种常见的做法是大改语法引入maybe关键字支持代数类型 并且函数做模式
  • 攻防世界—file_include

    打开之后发现是一段php代码 可以看出这是段代码有文件包含漏洞 下面是学习部分 着急看题解继续往下滑 谢谢 文件包含漏洞 File Inclusion Vulnerability 是一种Web应用程序常见的安全漏洞 也是攻击者常用的攻击手段
  • 自激振荡现象

    理论上说 自激振荡是指当放大器加电后 还没有加载输入信号 输出端就出现了高频的类似于正弦波一样的波形 实际中 还有另外一种情况 也属于自激振荡 当输入某些信号时 输出是正常的 一旦改变输入信号幅度或者频率到某些特定值 输出波形在原基础上会叠
  • redis概述、不同系统安装以及redis配置文件redis.conf各参数详细介绍

    目录 redis简介 简介 特点 优势 redis与其他key value数据库的区别 redis的安装 windows linux ubuntu下安装 redis配置 redis数据类型 String 字符串 Hash 哈希 List 列
  • 【总结】LinkedBlockingQueue为什么可以实现双锁算法

    LinkedBlockingQueue 双锁算法 putLock takeLock 为什么可以实现 put操作是将新节点放在队尾 take操作是将队首的节点取出 故两操作是满足FIFO 这在队列不为空时 避免了put和take会操作同一个元
  • JavaScript 节流和防抖

    前言 本文主要记录了JavaScript 节流和防抖 节流和防抖本质上是优化执行高频率代码的一种手段 例如 浏览器的 mousemove resize scroll 等事件在触发时 会不断地调用绑定的事件函数极大地降低了前端的性能 为了性能
  • C#、js如何实现文件上传功能

    上传文件 今天我来讲讲在MVC中如何进行文件的上传 我们逐步深入 一起来看看 我们在默认创建的项目中的控制器下添加如下 第一步创建一个接受文件的实体 创建好后判断一下接受文件的是什么文件类型如txt 然后就是文件名称建好后检查目录文件是否存
  • CVPR2017-如何在无标签数据集上训练模型

    论文 Fine tuning Convolutional Neural Networks for Biomedical Image Analysis Actively and Incrementally 论文链接 http openacce
  • 深入解析Spring Boot中最常用注解的使用方式(下篇)

    摘要 本文是 深入解析Spring Boot中最常用注解的使用方式 的下篇内容 将继续介绍Spring Boot中其他常用的注解的使用方式 并通过代码示例进行说明 帮助读者更好地理解和运用Spring Boot框架 目录 第二部分 常见的容
  • 全国职业技能大赛云计算--高职组赛题卷④(容器云)

    全国职业技能大赛云计算 高职组赛题卷 容器云 第二场次题目 容器云平台部署与运维 任务1 Docker CE及私有仓库安装任务 5分 任务2 基于容器的web应用系统部署任务 15分 任务3 基于容器的持续集成部署任务 15分 任务4 Ku
  • 哈希表的设计

    概念 顺序结构以及平衡树 中 元素关键码与其存储位置之间没有对应的关系 因此在 查找一个元素时 必须要经过关键 码的多次比较 顺序查找时间复杂度为 O N 平衡树中为树的高度 即 O 搜索的效率取决于搜索过程中 元素的比较次数 理想的搜索方
  • 主页自定义可拖动组件 2.0版本 (portlet)

    首先 我是从下面这个页面抠出来的 http wrapbootstrap com preview WB00958H8 效果 在这个页面直接右键查看源代码 就可以看到了 非常清楚 因为我就只用这么一个portlet功能 我就给抠下来了 原来的代
  • webservice ajax课程,net webservice ajax访问

    function getdata click function ajax type Post url http localhost 65497 WebSite1 WebService asmx GetAge id 3344 data id
  • onload和ready的区别

    三个方面 window onload document ready 执行时机 必须等待网页全部加载完毕 包括图片等 然后再执行包裹代码 只需要等待网页中DOM结构加载完毕 就能执行包裹的代码 执行次数 只能执行一次 如果第二次 那么第一次的
  • 性能优化——设计更优的分布式锁?

    那什么是分布式锁呢 它又是用来解决哪些问题的呢 在 JVM 中 在多线程并发的情况下 我们可以使用同步锁或 Lock 锁 保证在同一时间内 只能有一个线程修改共享变量或执行代码块 但现在我们的服务基本都是基于分布式集群来实现部署的 对于一些