在电商项目中,经常有秒杀这样的活动促销,在并发访问下,很容易出现上述问题。如果在库存操作上,加锁就可以避免库存卖超的问题。分布式锁使分布式系统之间同步访问共享资源的一种方式

基于redis实现分布式锁的原理:

  redis为单进程单线程模式,采用队列模式将并发访问变成串行访问,且多客户端对Redis的连接并不存在竞争关系。其次Redis提供一些命令SETNX,GETSET,这些命令是原子操作,利用这些特性,

可以很充分的实现分布式锁。SETNX,GETSET 命令如下:

  SETNX key value

    功能:当且仅当 key 不存在,将 key 的值设为 value ,并返回1;若给定的 key 已经存在,则 SETNX 不做任何动作,并返回0。

  GETSET key value

    功能:将给定 key 的值设为 value ,并返回 key 的旧值 (old value),当 key 存在但不是字符串类型时,返回一个错误,当key不存在时,返回null

 实现要点:

  1、避免死锁,必要的超时机制。设置时间戳,时间戳要精确到毫秒。如果获取锁失败,则说明锁被其他对象保持,检查其是否超时

  2、释放锁时,避免释放非自己获得的锁,释放锁时,可以做一个是否超时的检查,如果超时说明锁就无需释放了

  3、为了造成不必要的资源浪费,提高并发,最好在最小颗粒度上的块加锁

  4、为了降低redis 压力,获取锁尝试时,循环之间一定要做sleep操作



参考源代码如下

// redis client

private Redistemplate tradeRedisTemplate



private Boolean setNX(String key, String value){

   return redisConnection.setNX(key.bytes, value.bytes)   

}



private String getSet(String key, String value){

   byte[] result = redisConnection.getSet(key.bytes, value.bytes)

   return new String(result)

}



//释放锁  key 锁名称,time 超时时间

public Void delDistributedLock(String key, Long time){

        String lastTimeS = tradeRedisTemplate.opsForValue().get(key)

        if(System.currentTimeMillis() - Long.parseLong(lastTimeS) < time){//避免删除非自己获取得到的锁

            tradeRedisTemplate.delete(key)

        }

}



//加锁 key 锁名称,time 超时时间

public Boolean acquireDistributedLock(String key, Long time){

        if(setNX(key, Long.toString(System.currentTimeMillis()))){ //SETNX成功,则成功获取一个锁

            return true

        }else{

            //SETNX失败,说明锁仍然被其他对象保持,检查其是否已经超时

            String lastTimeS = tradeRedisTemplate.opsForValue().get(key)

Long lastTime = Long.parseLong(lastTimeS)

//超时

            if(System.currentTimeMillis() - lastTime > time){

                String lastTimeRedis = getSet(key, Long.toString(System.currentTimeMillis()))

                if(lastTimeRedis.equals(lastTimeS)){// 获取锁成功

                    return true

                }

                // 已被其他进程捷足先登了

            }

        }

        return false

}

参考资料:

http://redis.io/commands/setnx

http://www.blogjava.NET/caojianhua/archive/2013/01/28/394847.html

基于redis 实现分布式锁的方案的更多相关文章

  1. 基于redis的分布式锁实现方案--redisson

    实例代码地址,请前往:https://gitee.com/GuoqingLee/distributed-seckill redis官方文档地址,请前往:http://www.redis.cn/topi ...

  2. 基于Redis的分布式锁真的安全吗?

    说明: 我前段时间写了一篇用consul实现分布式锁,感觉理解的也不是很好,直到我看到了这2篇写分布式锁的讨论,真的是很佩服作者严谨的态度, 把这种分布式锁研究的这么透彻,作者这种技术态度真的值得我好 ...

  3. 基于 redis 的分布式锁实现 Distributed locks with Redis debug 排查错误

    小结: 1. 锁的实现方式,按照应用的实现架构,可能会有以下几种类型: 如果处理程序是单进程多线程的,在 python下,就可以使用 threading 模块的 Lock 对象来限制对共享变量的同步访 ...

  4. 基于redis 实现分布式锁(二)

    https://blog.csdn.net/xiaolyuh123/article/details/78551345 分布式锁的解决方式 基于数据库表做乐观锁,用于分布式锁.(适用于小并发) 使用me ...

  5. 从零到一手写基于Redis的分布式锁框架

    1.分布式锁缘由 学习编程初期,我们做的诸如教务系统.成绩管理系统大多是单机架构,单机架构在处理并发的问题上一般是依赖于JDK内置的并发编程类库,如synchronize关键字.Lock类等.随着业务 ...

  6. 基于Redis的分布式锁到底安全吗(下)?

    2017-02-24 自从我写完这个话题的上半部分之后,就感觉头脑中出现了许多细小的声音,久久挥之不去.它们就像是在为了一些鸡毛蒜皮的小事而相互争吵个不停.的确,有关分布式的话题就是这样,琐碎异常,而 ...

  7. 基于Redis的分布式锁到底安全吗(上)?

    基于Redis的分布式锁到底安全吗(上)?  2017-02-11 网上有关Redis分布式锁的文章可谓多如牛毛了,不信的话你可以拿关键词“Redis 分布式锁”随便到哪个搜索引擎上去搜索一下就知道了 ...

  8. 基于Redis的分布式锁安全性分析-转

    基于Redis的分布式锁到底安全吗(上)?  2017-02-11 网上有关Redis分布式锁的文章可谓多如牛毛了,不信的话你可以拿关键词“Redis 分布式锁”随便到哪个搜索引擎上去搜索一下就知道了 ...

  9. 基于Redis的分布式锁和Redlock算法

    1 前言 前面写了4篇Redis底层实现和工程架构相关文章,感兴趣的读者可以回顾一下: Redis面试热点之底层实现篇-1 Redis面试热点之底层实现篇-2 Redis面试热点之工程架构篇-1 Re ...

随机推荐

  1. 时隔两个月再写的Echarts(Enterprise Charts,商业级数据图表)一文

    简介 ECharts,缩写来自Enterprise Charts,商业级数据图表,一个纯Javascript的图表库,可以流畅的运行在PC和移动设备上,兼容当前绝大部分浏览器(IE6/7/8/9/10 ...

  2. Egret Wiing3快捷键

    删除当前行 ( Ctrl+Shift+k ),EgretWing2.5下为 Ctrl+D 折叠 ( Ctrl+Shift+[ ) 展开 ( Ctrl+Shift+] ) Ctrl+Shift+P呼出面 ...

  3. python语言中的编码问题

    在编程的过程当中,常常会遇到莫名其妙的乱码问题.很多人选择出了问题直接在网上找答案,把别人的例子照搬过来,这是快速解决问题的一个好办法.然而,作为一个严谨求实的开发者,如果不从源头上彻底理解乱码产生的 ...

  4. window下的各种宽高度小结

    详细的请打开这里看console.log window.innerWidth:  文档显示区(body)的宽度window.innerHeight  文档显示区(body)的高度window.outr ...

  5. AngularJS下对数组的比较

    Javascript不能直接用==或者===来判断两个数组是否相等,无论是相等还是全等都不行,以下两行JS代码都会返回false <script type="text/javascri ...

  6. 深度剖析 | 基于大数据架构的BI应用

    说起互联网.电商的数据分析,更多的是谈应用案例,如何去实践数据化管理运营.而这里,我们要从技术角度分享关于数据的技术架构干货,如何应用BI. 原文是云猴网BI总经理王卫东在帆软大数据上的演讲,以下是整 ...

  7. Sqlite 存储自定义对象

    在iOS中如果想保存自定义对象,要让自定义对象实现NSCoding接口并实现方法-(id)initWithCoder:(NSCoder *)coder和-(void)encodeWithCoder:( ...

  8. Unity3D安卓出包报错

    今天又遇到了在安卓出包时,直接报错了两个错误,报错信息分别如下: Installation failed with the following output: pkg: /data/local/tmp ...

  9. [Modern OpenGL系列(一)]十步搞定OpenGL开发环境

    本文已同步发表在CSDN:http://blog.csdn.net/wenxin2011/article/details/51292143 OpenGL官网:https://www.opengl.or ...

  10. SQL删除语句同时向备份表插入数据

    从这里摘抄下来的,觉得很不错,http://www.cnblogs.com/ljhdo/p/5792886.html#3503524 ,以后就用这种方式删除,再也不用担心删除错数据啦!!!