如何使用redis实现分布式锁
为什么要使用分布式锁?场景?
涉及到重复提交或交易的地方
场景一:提交订单
用户购买商品,下单时,有时不小心连续点击多次;
或者网络不好,导致用户以为没有提交,重复点击提交按钮;
网络层面比如nginx的重发.
对于分布式系统,提交订单的n个请求可能会被不同的服务单体消费,
那么就会生成多个相同(除了订单号,其他购买信息完全一样)的订单,
后果:
- 产生了脏数据,影响了校验,有时甚至会影响正常业务的执行;
- 前端用户会发现产生了多个订单,让用户迷茫,不知所措.
场景二:
有哪些解决方法呢?
使用其他方式实现分布式锁
参考: 分布式系统后台如何防止重复提交
使用redis
流程如下:
代码如下:
/*** * 提交订单 * @param model * @param request * @param response * @return */ @ResponseBody @RequestMapping(value = "/order/submit/json", produces = SystemHWUtil.RESPONSE_CONTENTTYPE_JSON_UTF) public String jsonSubmitOrder2(Model model, HttpServletRequest request, HttpServletResponse response , @RequestParam(required = false) Boolean del) { //可以抽取出常量 String lockUniquePrefix = "lock"; Jedis jedis = getJedis(); //1. 获取锁 // key:"lock"+方法名,value:时间戳 //NX -- Only set the key if it does not already exist. String key = lockUniquePrefix + Thread.currentThread().getStackTrace()[1].getMethodName(); //"OK":成功;null:失败 String result = jedis.set(key, "aa", "NX", "EX"/*seconds*/, 1000); Const.pool.returnResource(jedis); boolean success = "OK".equals(result); System.out.println("success :" + success); System.out.println("result :" + result); if (success) { //2. 执行具体业务逻辑 //... } //3. 业务逻辑执行完成之后,释放锁 jedis = getJedis(); jedis.del(key); Const.pool.returnResource(jedis); return BaseResponseDto.put2("result", result).put("success", success).toJson(); }
为什么jedis.set方法中要使用"NX"呢? 因为只有当key不存在时,操作才会成功, 即key不存在时,jedis.set返回"OK",表示获取锁成功; key存在时,jedis.set返回null,表示获取锁失败
为什么要使用redis
因为关于锁有两个重要的操作:
- 获取锁;
- 释放锁.
在分布式环境,必须保证这两个操作是原子性的,
即不能把获取锁分为两步:先查询,再add.
同时,获取锁时,能够设置有效期.
分布式锁实现时要注意的问题
- 提供锁的服务必须是一个唯一的服务,即负载均衡的n个服务单体访问的是同一个服务;
- 能够设置锁的有效期,不能让某个消费者永久地持有锁;
- 能够释放锁;
- 不同的业务逻辑竞争不同的锁,必须下单和减库存 使用不同的锁.
redis 还能做什么
redis除了可以实现分布式锁,还能作为缓存服务器,
在实现需求中,我经常把一些容易变化的配置放在redis中, 这样当产品经理需求变更时,我只需修改redis,即时生效,不用上线
参考:
https://my.oschina.net/huangweiindex/blog/1853160
相关推荐
redis实现分布式锁,自旋式加锁,lua原子性解锁
主要介绍了Java基于redis实现分布式锁代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
redis实现分布式锁(java/jedis),其中包含工具方法以及使用demo 本资源是利用java的jedis实现 redis实现分布式锁(java/jedis),其中包含工具方法以及使用demo 本资源是利用java的jedis实现
用Redis实现分布式锁的简易教程,在ppt中附有代码解析
自己封装redisson方法,同时通过注解的方式加入redis分布式事务锁,可靠。
C++的redis的API、 需要boost库、可直接加入工程目录编译
自己整理的如何利用redis实现分布式锁,redis实现分布式锁看这一篇绝对够。
用Redis实现分布式锁 与 实现任务队列
redis实现分布式锁 通过lua脚本和redisson两种方式实现分布式锁
分布式锁有很多种解决方案,今天我们要讲的是怎么使用缓存数据库Redis来实现分布式锁。 课程目标: 理解redis分布式锁的应用场景 掌握redis分布式锁的实现原理 掌握redis分布式锁在微服务项目中的应用 掌握...
之前看很多人手写分布式锁,其实 Spring Boot 现在已经做的足够好了,开箱...本篇栈长以 Redis 为例(这也是用得最多的方案),教大家如何利用 Spring Boot 集成 Redis 实现缓存,如何简单、快速实现 Redis 分布式锁。
基于go和redis实现分布式锁,使用了看门狗和红锁
主要为大家详细介绍了SpringBoot使用Redis实现分布式锁,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
基于Redis方式实现分布式锁
现在很多项目单机版已经不满足了,分布式变得越受欢迎,同时也带来很多问题,分布式锁也变得没那么容易实现,分享一个redis分布式锁工具类,里面的加锁采用lua脚本(脚本比较简单,采用java代码实现,无须外部调用...
redis实现分布式锁 数据库实现分布式锁 zk实现分布式锁 今天我们介绍通过redis实现分布式锁。实际上这三种和java对比看属于一类。都是属于程序外部锁。 原理剖析 上述三种分布式锁都是通过各自为依据对各个请求...
用注解实现redis分布式锁,防止短时间内重复请求,尤其对于请求耗时较长的方法,希望对大家有帮助
本资源为一步一步实现redis分布式锁的demo,利用redis实现高可用的分布式锁,规避各种坑、坑、坑!
redisTemplate封装成redisUtils和分布式锁实现,亲测可用
分布式锁是在分布式环境下(多个JVM进程)控制多个客户端对某一资源的同步访问的一种实现,与之相对应的是线程锁,线程锁控制的是同一个JVM进程内多个线程之间的同步。分布式锁的一般实现方法是在应用服务器之外通过...