博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
互金平台使用redis分布式锁的场景分析
阅读量:4037 次
发布时间:2019-05-24

本文共 1142 字,大约阅读时间需要 3 分钟。

使用场景:
1、服务器采用分布式集群(多个tomcat)和公用的redis
2、业务场景:多个用户同时下单的高并发情况下,为了保证库存一致,避免超卖的情况,可以考虑在减库存的操作当中进行加锁操作
3、尝试加锁,如果加锁失败则等待一段时间重试;如果加锁成功,则拿当前购买金额和redis中的库存金额进行比较
4、如果大于库存金额,则提示用户当前库存金额不足,请重新下单
5、如果小于库存金额,则进行减库存操作
6、完成4/5操作后立即释放锁,并执行下面的业务操作(更新数据库库存,更新账户信息,记录流水,记录客户订单)
7、异常情况:
(1)业务处理失败,数据回滚,则返回用户下单失败,并还原库存(同时对库存操作进行加锁,保持数据一致)
(2)获取锁的线程超时,则抛出异常,返回给客户端下单超时
8、在生成产品时候,同时在redis中存储该产品的库存
使用redis实现的分布式锁:
首先设置每个获取锁的线程的超时时间,如果超过时间没有获取到锁则抛出超时异常;(锁等待超时,防止线程饥饿,永远没有入锁执行代码的机会 )
如果在时间范围则一直尝试获取锁;执行下列操作:
 1、通过jedis.setnx(key,value)命令,设置锁的有效时间(防止死锁)
key存放的该产品的唯一标识
value存放的当前时间+超时时间
(注:set if Not eXist 保证多个线程同一时间请求时,只有一个线程能获得锁;类似zookeeper的新增一个节点)
2、result 成功获得锁返回 1,否则 返回0
3、其它没有获得锁的线程,不断进行重试:
(1)判断锁是否正常释放
通过setnx(key,value)命令判断返回值是否为1
(2)判断锁是否已经超时
①通过get(key)获取到当前存储的超时时间curTime
②判断当前时间是否超时,如果超时进行步骤③,未超时则
③如果超时,则通过jedis的getset(key)命令,获取到当前key的旧值oldTime,并重新设置新的值即超时时间;
④并判断oldTIME和curTime是否相等,如果相等
则当前线程获得锁
⑤没有获得锁,等待一段时间后,继续执行第(1)步操作
⑥获取到锁,执行业务逻辑,finally释放锁
⑦释放锁,使用jedis.del(key),并把锁的标志置为false
(注:getset(key)是同步的,确保只有一个线程能获取到最原始的超时时间)
注意:里边牵涉到两个超时时间
1、锁等待超时,防止线程饥饿,永远没有入锁执行代码的机会
2、锁的超时时间,防止异常情况导致一个线程一直占有锁操作

具体代码实现参考:http://www.cnblogs.com/0201zcr/p/5942748.html

你可能感兴趣的文章
PHP那点小事--三元运算符
查看>>
解决国内NPM安装依赖速度慢问题
查看>>
Brackets安装及常用插件安装
查看>>
Centos 7(Linux)环境下安装PHP(编译添加)相应动态扩展模块so(以openssl.so为例)
查看>>
fastcgi_param 详解
查看>>
Nginx配置文件(nginx.conf)配置详解
查看>>
标记一下
查看>>
一个ahk小函数, 实现版本号的比较
查看>>
IP报文格式学习笔记
查看>>
autohotkey快捷键显示隐藏文件和文件扩展名
查看>>
Linux中的进程
查看>>
学习python(1)——环境与常识
查看>>
学习设计模式(3)——单例模式和类的成员函数中的静态变量的作用域
查看>>
自然计算时间复杂度杂谈
查看>>
当前主要目标和工作
查看>>
Intellij IDEA启动优化,让开发的感觉飞起来
查看>>
使用 Springboot 对 Kettle 进行调度开发
查看>>
如何优雅的编程,lombok你怎么这么好用
查看>>
一文看清HBase的使用场景
查看>>
除了负载均衡,Nginx还可以做很多,限流、缓存、黑白名单
查看>>