近期一项需求需要使用分布式锁,考虑的方案主要有如下两种:

  1. zookeeper
  2. codis

因为对于zookeeper不是特别熟悉,因此选用了codis,Codis是一个分布式的Redis解决方案,从应用层面上看几乎和redis是一样的,我之所以说是几乎,就是因为这里踩了一个坑!

我们都知道,redis中有事务的概念,对应着有事务的命令:

  1. DISCARD
  2. EXEC
  3. MULTI
  4. UNWATCH
  5. WATCH

本以为codis与redis一样支持事务,毕竟语法层面提供了上述的命令,于是分布式锁第一个版本诞生了:

 public boolean lock(String key, String value, int expireTime) {
// 开启事务
Transaction transaction = codis.multi();
// setnx方法:如果已经存在key,则不设置值,并返回0,反之设置value,返回1
Long result = codis.setnx(key, value);
// 如果成功了,则设置过期时间
if (result > 0) {
codis.expire(key, expireTime);
}
// 执行上述两个命令
transaction.exec();
return result > 0;
}

主要是运用了setnx、expire方法,逻辑上述注释已做说明不再赘述!

在不考虑宕机的情况,理论上应该是可以的,但是实际上运行却出现如下结果:

io.codis.jodis.bo.UnsupportedMethodException: unsupport multi()

令人沮丧,居然提供命令却不能在运行时支持~

事后查了一下codis的文档,确实是不支持的,没办法只能该用其他方式,最后采用了网络上一种较为合适的方式,代码如下:

 public boolean lock(String sign, int expireTime) {
String currentTime = String.valueOf(System.currentTimeMillis() + expireTime * 1000);
Long result =codis.setnx(sign, currentTime);
if (result > 0) {
return true;
}
// 若设置失败,则校验codis中的值是否已经过期(宕机导致未删除)
String cacheTime = codis.get(sign);
if (StringUtils.isNotBlank(cacheTime) && Long.parseLong(cacheTime) < System.currentTimeMillis()) {
String oldTime = codis.getSet(sign, currentTime);
return cacheTime.equals(oldTime);
}
return false;
}

Codis分布式锁的更多相关文章

  1. redis 分布式锁实现

    我们实现的分布式锁,使用redis提供的SET NX功能,由于redis server的单线程模型,保证了天然并发安全. https://stackoverflow.com/questions/116 ...

  2. 使用redis构建可靠分布式锁

    关于分布式锁的概念,具体实现方式,直接参阅下面两个帖子,这里就不多介绍了. 分布式锁的多种实现方式 分布式锁总结 对于分布式锁的几种实现方式的优劣,这里再列举下 1. 数据库实现方式 优点:易理解 缺 ...

  3. 分布式锁1 Java常用技术方案

    前言:       由于在平时的工作中,线上服务器是分布式多台部署的,经常会面临解决分布式场景下数据一致性的问题,那么就要利用分布式锁来解决这些问题.所以自己结合实际工作中的一些经验和网上看到的一些资 ...

  4. .net 分布式架构之分布式锁实现

    分布式锁 经常用于在解决分布式环境下的业务一致性和协调分布式环境. 实际业务场景中,比如说解决并发一瞬间的重复下单,重复确认收货,重复发现金券等. 使用分布式锁的场景一般不能太多. 开源地址:http ...

  5. 分布式任务&分布式锁(li)

    目前系统中存在批量审批.批量授权等各个操作,批量操作中可能因为处理机器.线程不同,造成刷新缓存丢失授权等信息,如批量审批同一用户权限多个权限申请后,流程平台并发的发送多个http请求到acl不同服务器 ...

  6. jedisLock—redis分布式锁实现

    一.使用分布式锁要满足的几个条件: 系统是一个分布式系统(关键是分布式,单机的可以使用ReentrantLock或者synchronized代码块来实现) 共享资源(各个系统访问同一个资源,资源的载体 ...

  7. ZooKeeper 笔记(6) 分布式锁

    目前分布式锁,比较成熟.主流的方案有基于redis及基于zookeeper的二种方案. 大体来讲,基于redis的分布式锁核心指令为SETNX,即如果目标key存在,写入缓存失败返回0,反之如果目标k ...

  8. 一次基于etcd的分布式锁自动延时失败问题的排查

    今天在测试基于etcd的分布式锁过程中,在测试获取锁后,释放之前超出TTL时长的情况下自动延长TTL这部分功能,在延长指定key的TTL时总是返回404错误信息,在对目标KEY更新TTL时目标KEY已 ...

  9. 基于redis 实现分布式锁的方案

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

随机推荐

  1. mybatis入门介绍一

    首先介绍一下Mybatis是什么?mybatis是Java的持久层框架, JAVA操作数据库是通过jdbc来操作的,而mybatis是对jdbc的封装. 使用mybatis之后,开发者只需要关注sql ...

  2. python 密码学编程

    最近在看一本书.名字是 python密码学编程.在此做一些笔记,同时也为有需要的人提供一些参考. *************************************************** ...

  3. mysql控制台出现“unknown column 'password' in 'field list'问题

    今天在windows系统上使用MySQL命令时,出现下面的"unknown column 'password' in 'field list'问题 解决办法如下,使用authenticati ...

  4. (3)markdown软件的使用

    运行Mou.zip解压出来一个软件,它让托到应用程序中,然后打开 另一种软件为gitBook 安装好软件后,使用快捷键F4可以调出所有的应用程序 使用md(markdown简称)有个缺点就是,当内容比 ...

  5. SpringBoot基础梳理

    1.入口类和@SpringBootApplication注解: SpringBoot通常有一个名为*Application的入口类,入口类里面有main方法,我们可以通过启动main方法启动sprin ...

  6. 如何开发自己的搜索帝国之Elasticsearch

    搜索引擎是什么? 搜索引擎是指根据一定的策略.运用特定的计算机程序从互联网上搜集信息,在对信息进行组织和处理后,为用户提供检索服务,将用户检索相关的信息展示给用户的系统.搜索引擎包括全文索引.目录索引 ...

  7. 8. Andrénalin ★ Serial

    无花无壳爆破/硬编码 istcmp字符串比较 "<BrD-SoB>" 仅允许非商业转载,转载请注明出处

  8. C#之隐式与显示类型转换

    今天在看一篇有关数据类型的文章的时候,无意间看到了两个关键词,"隐式转换"与"显示转换",然后突然想起了当初开始学编程的时候,也总是在代码编译的时候遇到这样的问 ...

  9. linux 编译安装详解

    相信大家大多都听过linux 的编译安装,但它到底是怎么把源代码变为自己电脑里可以应用的软件哪?今天,小编就以httpd 为例详细讲解一下. 什么是编译安装--编译:将源代码变为机器可执行的代码文件. ...

  10. Git基础命令的使用

    当前git版本: git version 2.9.2.windows.1 1.创建一个能与git服务器连接的本地git库 本地:  git init git status (-s) git add . ...