redis实现分布式锁

原创 2018年04月17日 17:13:13

public class RedisTool {

private static final String LOCK_SUCCESS = "OK";
private static final String SET_IF_NOT_EXIST = "NX";
private static final String SET_WITH_EXPIRE_TIME = "PX";

/**
 * 尝试获取分布式锁
 * @param jedis Redis客户端
 * @param lockKey 锁
 * @param requestId 请求标识
 * @param expireTime 超期时间
 * @return 是否获取成功
 */
public static boolean tryGetDistributedLock(Jedis jedis, String lockKey, String requestId, int expireTime) {

    String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);

    if (LOCK_SUCCESS.equals(result)) {
        return true;
    }
    return false;

}


private static final Long RELEASE_SUCCESS = 1L;

/**
 * 释放分布式锁
 * @param jedis Redis客户端
 * @param lockKey 锁
 * @param requestId 请求标识
 * @return 是否释放成功
 */
public static boolean releaseDistributedLock(Jedis jedis, String lockKey, String requestId) {

    String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
    Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));

    if (RELEASE_SUCCESS.equals(result)) {
        return true;
    }
    return false;

}

}

可以看到,我们解锁只需要两行代码就搞定了!第一行代码,我们写了一个简单的Lua脚本代码,上一次见到这个编程语言还是在《黑客与画家》里,没想到这次居然用上了。

第二行代码,我们将Lua代码传到jedis.eval()方法里,并使参数KEYS[1]赋值为lockKey,ARGV[1]赋值为requestId。eval()方法是将Lua代码交给Redis服务端执行。

那么这段Lua代码的功能是什么呢?其实很简单,首先获取锁对应的value值,检查是否与requestId相等,

如果相等则删除锁(解锁)。那么为什么要使用Lua语言来实现呢?因为要确保上述操作是原子性的。关于非原子性会带来什么问题,可以阅读【解锁代码-错误示例2】 。

那么为什么执行eval()方法可以确保原子性,源于Redis的特性:

简单来说,就是在eval命令执行Lua代码的时候,Lua代码将被当成一个命令去执行,并且直到eval命令执行完成,Redis才会执行其他命令。

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012441924/article/details/79977675

基于redis的分布式锁的实现

之前一直对分布式锁有所思考。一直觉得现在高性能的redis是个不错的选择; 关于分布式锁的思考 今天也尝试着写了一个基于redis的分布式锁工具 LockUtil.java package yyf...
  • qq_18860653
  • qq_18860653
  • 2017-02-07 10:51:09
  • 2358

分布式锁的作用及实现(Redis)

一、什么是分布式锁?要介绍分布式锁,首先要提到与分布式锁相对应的是线程锁、进程锁。线程锁:主要用来给方法、代码块加锁。当某个方法或代码使用锁,在同一时刻仅有一个线程执行该方法或该代码段。线程锁只在同一...
  • L_BestCoder
  • L_BestCoder
  • 2018-02-19 15:29:38
  • 1502

基于Redis实现简单的分布式锁

在分布式场景下,有很多种情况都需要实现最终一致性。在设计远程上下文的领域事件的时候,为了保证最终一致性,在通过领域事件进行通讯的方式中,可以共享存储(领域模型和消息的持久化数据源),或者做全局XA事务...
  • hupoling
  • hupoling
  • 2016-11-30 17:47:59
  • 2776

使用Redis实现分布式锁

1.实现分布式锁的几种方案     1.Redis实现   (推荐)     2.Zookeeper实现     3.数据库实现 Redis实现分布式锁 * * 在集群等多服务器中经常使用...
  • he90227
  • he90227
  • 2017-04-07 16:28:24
  • 4948

架构师日记——基于redis的分布式锁实现

很久之前有讲过并发编程中的锁 并发编程的锁机制:synchronized和lock 。在单进程的系统中,当存在多个线程可以同时改变某个变量时,就需要对变量或代码块做同步,使其在修改这种变量时能够...
  • qq_32198277
  • qq_32198277
  • 2018-01-06 13:45:32
  • 306

利用多写Redis实现分布式锁原理与实现分析

在我写这篇文章的时候,其实我还是挺纠结的,因为我这个方案本身也是雕虫小技拿出来显眼肯定会被贻笑大方,但是我最终还是拿出来与大家分享,我本着学习的态度和精神,希望大家能够给与我指导和改进方案。 一、...
  • u013970991
  • u013970991
  • 2016-10-02 08:26:57
  • 22277

使用redis和zookeeper实现分布式锁

redis和zookeeper实现分布式锁
  • haitunlianren
  • haitunlianren
  • 2017-07-01 14:18:21
  • 542

Redis实现分布式锁原理与实现分析

一、关于分布式锁 关于分布式锁,可能绝大部分人都会或多或少涉及到。  我举二个例子:  场景一:从前端界面发起一笔支付请求,如果前端没有做防重处理,那么可能在某一个时刻会有二笔一样的单子...
  • jp413670706
  • jp413670706
  • 2016-10-05 08:02:04
  • 6953

基于Redis实现的分布式锁

基于Redis的分布式锁实现背景 根据redis的setnx命令实现只有一个客户端可以拿到锁; RedissonLock的分布式锁实现使用了lua脚本,这里提供一种不适用脚本实现的方法; 基本实现 使...
  • ljinshuan
  • ljinshuan
  • 2017-05-14 16:22:14
  • 570

redis、zookeeper分布式锁的实现

redis、zookeeper分布式锁的实现
  • u013673242
  • u013673242
  • 2017-07-12 16:15:51
  • 624
收藏助手
不良信息举报
您举报文章:redis实现分布式锁
举报原因:
原因补充:

(最多只允许输入30个字)