首页 > 其他分享 >十三、利用分布式锁解决超卖问题

十三、利用分布式锁解决超卖问题

时间:2023-05-28 22:11:36浏览次数:33  
标签:加锁 十三 redis 问题 setIfAbsent 线程 超卖 分布式

库存超卖问题

对于商城系统。超卖了一部分可以补获,12306对超卖问题更敏感。

JMeter的使用

 

 超卖演示&使用JMeter对购票功能进行压测

 

 使用synchronized是否能解决库存超卖?

超卖问题出现原因:

 假设余票为1,此时多个线程同时查询到这条余票记录,并进行扣减,那么则会导致超卖发生。

public synchronized void doConfirm(ConfirmOrderDoReq req)

加锁会导致吞吐量/TPS变低,即:售卖效率不高。

一个节点可以加锁,1万个节点呢?还是无法解决超卖。(加节点可以解决性能问题)

存在问题

  • 会导致售卖效率不高(可以容忍)
  • 在多节点的情况下,还是会出现超卖(不能容忍)。
  • 多个人抢多个车次也不应该受影响。

使用Redis分布式锁能否解决库存超卖?

解决超卖:所有节点都能得到的锁

可以通过数据库加锁,性能不高。

所以用redis加锁。

第一个线程进来setIfAbsent设置为true,此时其他线程不可入。

1 String key = req.getDate() + "-" + req.getTrainCode();
2         Boolean setIfAbsent = redisTemplate.opsForValue().setIfAbsent(key, key, 3600, TimeUnit.SECONDS);
3         if (setIfAbsent) {
4             LOG.info("恭喜,抢到锁啦!");
5         } else {
6             LOG.info("很遗憾,没有抢到锁");
7             throw new BusinessException(BusinessExceptionEnum.CONFIRM_ORDER_LOCK_FAIL);
8         }

key就用日期加车次号,value随意。没抢到有提示。

新的问题:

某一处出现异常会怎么样?必须过了超时时间才能进新的请求。

可以在方法结尾删除锁  redisTemplate.delete(lockKey);  

只能解决正常流程问题,异常还有待处理。

将整个set锁以下的部分加异常处理。

1 Boolean setIfAbsent = redisTemplate.opsForValue().setIfAbsent(lockKey, lockKey, 5, TimeUnit.SECONDS);
2         if (setIfAbsent) {
3             LOG.info("恭喜,抢到锁啦!");
4         } else {
5             LOG.info("很遗憾,没有抢到锁");
6             throw new BusinessException(BusinessExceptionEnum.CONFIRM_ORDER_LOCK_FAIL);
7         }

如果这部分也加了锁,没抢到锁也会抛异常,会把别人的锁给删掉。

  • 加锁的动作不要放在try里
  • 加锁时,将当前线程ID放到锁对应的value中,删除时,先去获取value,比对value值和当前线程ID一致时才能删除。

使用Redisson看门狗解决超时问题

之前的方法就是setnx命令。

最关键的问题是有超时时间,如果项目很大,卡住线程,锁释放掉,还会引起超卖问题。

设置守护线程(看门狗),不断重置超时时间。

使用守护线程的好处是会随主线程的结束而结束,所以不会出现一直重置成60s,永不过期的问题。

Redis红锁是什么

看门狗锁还会遇到redis宕机问题。

第1个线程拿到锁,redis宕机。第二个线程进来也会拿到锁。

如果有A B C D E台redis(不是集群),第1个线程进来拿到A B C,拿到半数以上的节点,就认为拿到了锁。要求必须是奇数台redis。

RedissonRedLock。

 

标签:加锁,十三,redis,问题,setIfAbsent,线程,超卖,分布式
From: https://www.cnblogs.com/szhNJUPT/p/17438981.html

相关文章

  • SpringCloudAlibaba整合分布式事务Seata
    目录1整合分布式事务Seata1.1环境搭建1.1.1Nacos搭建1.1.2Seata搭建1.2项目搭建1.2.1项目示意1.2.2pom.xml1.2.2.1alibaba-demo模块1.2.2.2call模块1.2.2.3order模块1.2.2.4common模块1.2.3配置文件1.2.3.1order模块1.2.3.2call模块1.2.4OpenFeign调用1.2.5order......
  • 微服务架构学习与思考(13):分布式配置中心
    一、配置中心的诞生用编程语言编写应用项目时,一般都会有项目的配置文件。比如用java编写项目,有一个properties的配置文件,会把一些配置信息写入到该文本文件中,例如数据库相关的配置信息。这也体现了软件设计的一个原则:关注点分离。把代码和配置信息相分离。​......
  • centos7上Hadoop2.7.2完全分布式部署
    1.规划node1         node2           node3datanode       datanode         datanodenamenode     resourcemanager  secondarynamenodenodemanager   nodemanager     no......
  • centos7.9上hadoop-2.7.2伪分布式部署
    1.安装jdk1.1在Oracle官网上现在jdk1.8,然后上传到Linux服务器中1.2 安装jdk rpm-ivhjdk-8u371-linux-x64.rpm2创建部署用户hadoopuseradd-d/hadoophadoopecho123|passwd--stdinhadoop3修改/etc/hosts4使用Hadoop用户上传hadoop安装包hadoop-2.7......
  • 使用Python实现分布式爬虫
    使用Python实现分布式爬虫在Web爬虫中,分布式爬虫已经成为一种流行的技术,可以帮助我们快速地收集互联网上的数据。下面我们将介绍如何使用Python实现分布式爬虫。什么是分布式爬虫?分布式爬虫是指将爬虫任务分配给多个计算机节点执行,以提高爬取效率和稳定性的一种技术。分布式爬虫通......
  • 分布式事务
    AT:AT模式是一种无侵入的分布式事务解决方案。阿里seata框架,实现了该模式TCC:TCC模式需要用户根据自己的业务场景实现Try、Confirm和Cancel三个操作;事务发起方在一阶段执行Try方式,在二阶段提交执行Confirm方法,二阶段回滚执行Cancel方法。TCC三个方法描述:Try:资源的检测......
  • 分布式机器学习(Parameter Server)
    分布式机器学习中,参数服务器(ParameterServer)用于管理和共享模型参数,其基本思想是将模型参数存储在一个或多个中央服务器上,并通过网络将这些参数共享给参与训练的各个计算节点。每个计算节点可以从参数服务器中获取当前模型参数,并将计算结果返回给参数服务器进行更新。为了保持......
  • 分布式CAP理论
    分布式:一个大业务拆分成多个小业务并部署在不同的服务器上CAP:一个分布式系统最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partitiontolerance)这三项中的两项。  网络问题不可避免,P(分区容错性)是一定需要保证的如果此时有节点故障,如果剩余节点正常......
  • 分布式基础之CAP理论&BASE理论
    1.CAP理论1.1)含义C(Consistency一致性)、Availability(可用性)、PartitionTolerance(分区容错性)。1.2)具体意义一致性(Consistency):所有节点访问同一份最新的数据副本可用性(Availability):非故障的节点在合理的时间内返回合理的响应(不是错误或者超时的响应)。分区容错性(Partition......
  • 配置GlusterFS分布式文件系统​
    拓扑图:推荐步骤:在Centos01到Centos04,在每台服务器创建四个分区格式化为XFS文件系统自动设置开机自动挂载在Centos01到Centos04安装glusterFS分布式存储系统创建配置glusterfs群集和创建分布式条带卷、分布式复制卷、分布式卷、条带卷实验步骤:一.在Centos01到Centos04,在每台服务器创......