`

如何使用redis实现分布式锁

阅读更多

如何使用redis实现分布式锁

为什么要使用分布式锁?场景?

涉及到重复提交或交易的地方

场景一:提交订单

提交订单

用户购买商品,下单时,有时不小心连续点击多次;
或者网络不好,导致用户以为没有提交,重复点击提交按钮;
网络层面比如nginx的重发.

对于分布式系统,提交订单的n个请求可能会被不同的服务单体消费,
那么就会生成多个相同(除了订单号,其他购买信息完全一样)的订单,

后果:

  1. 产生了脏数据,影响了校验,有时甚至会影响正常业务的执行;
  2. 前端用户会发现产生了多个订单,让用户迷茫,不知所措.

场景二:

有哪些解决方法呢?

使用其他方式实现分布式锁

参考: 分布式系统后台如何防止重复提交

使用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

因为关于锁有两个重要的操作:

  1. 获取锁;
  2. 释放锁.

在分布式环境,必须保证这两个操作是原子性的,
即不能把获取锁分为两步:先查询,再add.
同时,获取锁时,能够设置有效期.

分布式锁实现时要注意的问题

  1. 提供锁的服务必须是一个唯一的服务,即负载均衡的n个服务单体访问的是同一个服务;
  2. 能够设置锁的有效期,不能让某个消费者永久地持有锁;
  3. 能够释放锁;
  4. 不同的业务逻辑竞争不同的锁,必须下单和减库存 使用不同的锁.

redis 还能做什么

redis除了可以实现分布式锁,还能作为缓存服务器,
在实现需求中,我经常把一些容易变化的配置放在redis中, 这样当产品经理需求变更时,我只需修改redis,即时生效,不用上线

参考:

https://my.oschina.net/huangweiindex/blog/1853160

0
0
分享到:
评论
1 楼 cremains 2018-07-23  
 

相关推荐

    redis实现分布式锁,自旋式加锁,lua原子性解锁

    本文将深入探讨如何使用Redis实现分布式锁,以及如何利用自旋式加锁和Lua脚本实现原子性解锁。 首先,我们来理解分布式锁的基本概念。分布式锁是在多节点之间共享资源时,用于协调各个节点的访问控制机制。在分布式...

    Java基于redis实现分布式锁代码实例

    Java基于Redis实现分布式锁代码实例 分布式锁的必要性 在多线程环境中,资源竞争是一个常见的问题。例如,在一个简单的用户操作中,一个线程修改用户状态,首先在内存中读取用户状态,然后在内存中进行修改,然后...

    redis实现分布式锁(java/jedis)

    redis实现分布式锁(java/jedis),其中包含工具方法以及使用demo 本资源是利用java的jedis实现 redis实现分布式锁(java/jedis),其中包含工具方法以及使用demo 本资源是利用java的jedis实现

    C++基于redis的分布式锁redisAPI

    本文将深入探讨如何使用C++结合Redis实现分布式锁,并详细讲解Redis API在C++中的应用,以及如何处理与Boost库的集成。 首先,Redis是一个高性能的键值存储数据库,广泛用于缓存、消息队列、分布式锁等场景。分布式...

    使用Redis实现分布式锁.zip

    本文将深入探讨如何利用Redis实现分布式锁,并对比其与信号量的区别。 一、Redis分布式锁 1. **基本原理**:在Redis中,分布式锁通常通过`SETNX`(Set if Not eXists)命令或者`SET`命令配合`nx`和`ex`选项来创建...

    记录redisson实现redis分布式事务锁

    首先,Redis作为一个内存数据库,其高速读写性能使其成为实现分布式锁的理想选择。分布式锁的主要作用是在多节点环境下保证同一时刻只有一个节点可以执行特定操作,避免并发问题。Redisson的分布式锁通过`RLock`接口...

    基于 Redis 的分布式锁

    4. 性能与可用性:使用Redis实现分布式锁,可以保证很高的性能,因为Redis操作非常快速。同时,由于Redis支持主从复制和哨兵模式,提供了高可用性的保障。即便主节点不可用,通过故障转移,其他从节点可以迅速接管,...

    用Redis实现分布式锁_redis_分布式_

    Redis,作为一个高性能的键值存储系统,常被用于实现分布式锁,因为它提供了丰富的数据类型和原子操作。本教程将深入探讨如何利用Redis来构建分布式锁。 一、Redis分布式锁的优势 1. 响应速度:Redis是内存数据库...

    基于Redis方式实现分布式锁

    ### 基于Redis方式实现分布式锁 #### 分布式锁概述 分布式锁是一种常见的分布式系统协调机制,用于控制分布式环境下的多个...通过以上步骤,我们可以有效地使用Redis实现分布式锁的功能,提高系统的稳定性和性能。

    C#.net Redis分布式锁源码实现

    在C#.NET中使用Redis实现分布式锁,主要涉及以下几个步骤和概念: 1. 连接Redis:首先,你需要创建一个Redis连接。StackExchange.Redis库提供了`ConnectionMultiplexer`类,用于建立到Redis服务器的连接。你可以...

    springboot基于redis分布式锁

    不过,以上代码提供了一个基本的实现思路,帮助你理解如何在SpringBoot应用中使用Redis实现分布式锁。 通过提供的Word文档,你应该能够找到更详细的配置和使用步骤。记得在实际项目中根据具体需求进行调整,确保...

    SpringBoot使用Redis实现分布式锁

    SpringBoot 使用 Redis 实现分布式锁 分布式锁是指在分布式系统中,多个节点或机器之间对共享资源的访问进行控制和协调,以避免冲突和竞争的机制。SpringBoot 使用 Redis 实现分布式锁是指使用 SpringBoot 框架和 ...

    基于Redis的分布式锁的实现方案.pdf

    Redis,作为一种高性能的NoSQL数据库,因其支持原子操作和具备高可用性,成为实现分布式锁的理想选择。 文章指出,利用Redis的SET命令来实现锁机制是实现分布式锁的一个有效途径。SET命令在Redis中用于设置键值对,...

    redis分布式锁.zip

    下面将详细介绍如何使用 Redis 实现分布式锁以及其中可能遇到的问题和解决方案。 首先,我们需要理解分布式锁的基本概念。分布式锁是一种在分布式系统中协调不同节点对共享资源访问的机制。它确保在任何时刻只有一...

    redis实现分布式锁

    redis实现分布式锁 通过lua脚本和redisson两种方式实现分布式锁

    [PHP] 基于redis的分布式锁防止高并发重复请求.docx

    * Redis 锁:使用 Redis 中的锁机制来实现分布式锁。 * ZooKeeper 锁:使用 ZooKeeper 分布式协调系统中的锁机制来实现分布式锁。 在本文中,我们使用 Redis 中的锁机制来实现分布式锁。我们使用 Redis 的 SET 命令...

    C#实操控制并发之Lock和Redis分布式锁

    以下是一个简单的C# Redis分布式锁实现: ```csharp public bool TryAcquireLock(string lockKey, int lockTimeout) { var redis = ConnectionMultiplexer.Connect("localhost:6379"); var db = redis.Get...

    Redis实现分布式锁(附源码+讲义)

    分布式锁有很多种解决方案,今天我们要讲的是怎么使用缓存数据库Redis来实现分布式锁。 课程目标:  理解redis分布式锁的应用场景  掌握redis分布式锁的实现原理  掌握redis分布式锁在微服务项目中的应用  掌握...

    Go 中使用 Redis 实现分布式互斥锁.zip

    Go 中使用 Redis 实现分布式互斥锁Redsync Redsync 为 Go 提供了一个基于 Redis 的分布式互斥锁实现,详见本文。Ruby的参考库(由antirez开发)可在github.com/antirez/redlock-rb上找到。安装使用 go get 命令安装 ...

    redis实现分布式锁与java信号量.zip

    在实际项目中,`redis实现分布式锁与java信号量.md`文件可能详细介绍了如何将这些理论知识应用到实际代码中,包括连接Redis、设置和获取锁、释放锁、异常处理等步骤。而`项目说明.zip`文件则可能包含了一个实际的...

Global site tag (gtag.js) - Google Analytics