原文:http://blog.csdn.net/heyewu4107/article/details/71009712

高并发场景系列(一) 利用redis实现分布式事务锁,解决高并发环境下减库存

问题描述:某电商平台,首发一款新品手机,每人限购2台,预计会有10W的并发,在该情况下,如果扣减库存,保证不会超卖

方案一

利用数据库锁机制,对记录进行锁定,再进行操作

  1. SELECT * from goods where ID =1 for update;
  2. UPDATE goods set stock = stock - 1;

利用排它锁将并行转化为串行操作,但该方案的性能和用户体验较差

方案二

利用redis 实现分布式锁,

使用setnx命令(在key不存在时,创建并设置value 返回1,key存在时,会反回0)来获取锁,在业务逻辑中,我们可以通过这样的方案来操作

  1. Jedis client = jedisPool.getResource();
  2. while(client.setnx("lock",String.valueOf(System.currentTimeMillis())) == 0){
  3. Thread.sleep(10000);
  4. }
  5. ...........................
  6. style="white-space:pre">   </span>    client.del("lock")

方案二进阶

考虑到死锁问题,即现成A获取锁后,宕机了,导致锁一直无法释放,我们可以通过get命令获取锁的时间戳,通过他进行超时判断,并进行释放

  1. Long TIMEOUT_SECOUND = 120000L;
  2. Jedis client = jedisPool.getResource();
  3. while(client.setnx("lock",String.valueOf(System.currentTimeMillis())) == 0){
  4. Long lockTime = Long.valueOf(client.get("lock"));
  5. if (lockTime!=null && System.currentTimeMillis() > lockTime+TIMEOUT_SECOUND) {
  6. client.del("lock");
  7. }
  8. Thread.sleep(10000);
  9. }
  10. ...........................
  11. ...........................
  12. client.del("lock")

方案二加强

方案2的算法中,为了确保在非超时情况下,锁只能由有锁的线程进行释放,可以在value的时间戳中,拼上线程特征码

    1. Long TIMEOUT_SECOUND = 120000L;
    2. String featureCode = "machine01";
    3. Jedis client = jedisPool.getResource();
    4. while(client.setnx("lock",featureCode+":"+String.valueOf(System.currentTimeMillis())) == 0){
    5. Long lockTime = Long.valueOf(client.get("lock").substring(9));
    6. if (lockTime!=null && System.currentTimeMillis() > lockTime+TIMEOUT_SECOUND) {
    7. client.del("lock");
    8. }
    9. Thread.sleep(10000);
    10. }
    11. ...........................
    12. ...........................
    13. if (featureCode.equals(client.get("lock").substring(0, 8))) {
    14. client.del("lock");
    15. }

高并发场景系列(一) 利用redis实现分布式事务锁,解决高并发环境下减库存的更多相关文章

  1. 利用redis实现分布式事务锁,解决高并发环境下库存扣减

    利用redis实现分布式事务锁,解决高并发环境下库存扣减   问题描述: 某电商平台,首发一款新品手机,每人限购2台,预计会有10W的并发,在该情况下,如果扣减库存,保证不会超卖 解决方案一 利用数据 ...

  2. 利用redis 分布式锁 解决集群环境下多次定时任务执行

    定时任务: @Scheduled(cron= "0 39 3 * * *") public void getAllUnSignData(){ //检查任务锁,若其它节点的相同定时任 ...

  3. 利用redis实现分布式锁

    分布式锁一般有三种实现方式: 1. 数据库乐观锁: 2. 基于ZooKeeper的分布式锁: 3. 基于Redis的分布式锁: 这里大概说一下三种方式的优缺点,数据库乐观锁优点是实现简单,只需要for ...

  4. 利用redis实现分布式锁知识点总结及相关改进

    利用redis实现分布式锁知识点总结及相关改进 先上原文,本文只为总结及对相关内容的质疑并提出若干意见,原文内容更详细https://www.cnblogs.com/linjiqin/p/800383 ...

  5. 单机Redis实现分布式互斥锁

    代码地址如下:http://www.demodashi.com/demo/12520.html 0.准备工作 0-1 运行环境 jdk1.8 gradle 一个能支持以上两者的代码编辑器,作者使用的是 ...

  6. 利用Redis锁解决高并发问题

    这里我们主要利用Redis的setnx的命令来处理高并发. setnx 有两个参数.第一个参数表示键.第二个参数表示值.如果当前键不存在,那么会插入当前键,将第二个参数做为值.返回 1.如果当前键存在 ...

  7. 利用 Redis 锁解决高并发问题

    这里我们主要利用 Redis 的 setnx 的命令来处理高并发. setnx 有两个参数.第一个参数表示键.第二个参数表示值.如果当前键不存在,那么会插入当前键,将第二个参数做为值.返回 1.如果当 ...

  8. PHP利用Mysql锁解决高并发

    前面写过利用文件锁来处理高并发的问题的,现在我们说另外一个处理方式,利用Mysql的锁来解决高并发的问题 先看没有利用事务的时候并发的后果 创建库存管理表 CREATE TABLE `storage` ...

  9. 使用数据库乐观锁解决高并发秒杀问题,以及如何模拟高并发的场景,CyclicBarrier和CountDownLatch类的用法

    数据库:mysql 数据库的乐观锁:一般通过数据表加version来实现,相对于悲观锁的话,更能省数据库性能,废话不多说,直接看代码 第一步: 建立数据库表: CREATE TABLE `skill_ ...

随机推荐

  1. C后端设计开发 - 第6章-武技-常见组件上三路

    正文 第6章-武技-常见组件上三路 后记 如果有错误, 欢迎指正. 有好的补充, 和疑问欢迎交流, 一块提高. 在此谢谢大家了.

  2. System.getProperty方法中输出路径的方法

    package codegenerator;/** *@author Eilen *@date 2017年9月27日---下午3:15:09 *@描述: *@answer */public class ...

  3. 使用 Visual Studio 部署 .NET Core 应用 ——.Net Core 部署到Ubuntu 16.04

    .Net Core 部署到Ubuntu 16.04 中的步骤 1.安装工具 1.apache 2..Net Core(dotnet-sdk-2.0) 3.Supervisor(进程管理工具,目的是服务 ...

  4. 属性名、变量名与 内部关键字 重名 加&

    procedure TForm4.btn3Click(Sender: TObject); var MyQj: TQJson; MyPrinter: TPrinter; begin MyQj := TQ ...

  5. P1474 货币系统 Money Systems(完全背包求填充方案数)

    题目链接:https://www.luogu.org/problemnew/show/1474 题目大意:有V种货币,求用V种货币凑出面值N有多少种方案. 解题思路:就是完全背包问题,只是将求最大价值 ...

  6. C语言写随机数

    #include <stdio.h> #include <stdlib.h> #include <time.h> ; unsigned int rand0(); v ...

  7. Longest Palindromic Substring (最长回文字符串)——两种方法还没看,仍需认真看看

    Given a string S, find the longest palindromic substring in S. You may assume that the maximum lengt ...

  8. python读写xml文件

    python读取xml文件 xml文件是具有树状结构的,如果想要访问某个叶子结点,必须逐层获取其父结点,要读取某个叶子结点内容用text成员 使用前先加载xml工具包 try: import xml. ...

  9. aliyun服务器ubuntu系统+MySQL+SqlDeveloper

    首先按照 https://www.digitalocean.com/community/tutorials/how-to-install-mysql-on-ubuntu-16-04 https://w ...

  10. CentOS7.5安裝配置多协议下载器Aria2

    一.搭建 Aria2 以及 AriaNg Web UI 使用Docker构建的Aria2 参考 aria2-ariang-docker 以及 aria2-ariang-x-docker-compose ...