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

  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. ionic时间插件ion-datetime-picker

    https://github.com/katemihalikova/ion-datetime-picker

  2. 如何重置密码 oracle sys和system

    有时候我们会忘记oracle sys和system的密码,不用担心,通过sqlplus即可修改密码.只能修改,不能找回. 方法如下: 1.打开 cmd界面,输入sqlplus /nolog 显示结果如 ...

  3. ASP.NET Core MVC – 自定义 Tag Helpers

    ASP.NET Core Tag Helpers系列目录,共四篇: ASP.NET Core MVC Tag Helpers 介绍 ASP.NET Core MVC – Caching Tag Hel ...

  4. ubuntu系统普通用户sudo命令执行报错解决方案

    通过adduser user1命令创建普通用户,且使该用户具有sudo权限(将该新用户user1添加到sudo或root用户组中,或者修改/etc/sudoer文件),但是依然无法执行sudo指令,会 ...

  5. 轻松学JVM(一)——基本原理

    前言 JVM一直是java知识里面进阶阶段的重要部分,如果希望在java领域研究的更深入,则jvm则是如论如何也避开不了的话题,本系列试图通过简洁易读的方式,讲解jvm必要的知识点. 运行流程 我们都 ...

  6. cvim常用快捷键

      esc:返回浏览模式 h.j.k.l:上.下.左.右 u/e.d:上半屏.下半屏 H.L:后退.前进 f.F:直接打开.后台打开 gg.G:页头.页尾 gi.gI:第一个输入框.最后一个输入框 q ...

  7. JVM笔记——技术点汇总

    目录 · 初步认识 · Java里程碑(关键部分) · 理解虚拟机 · Java虚拟机种类 · Java语言规范 · Java虚拟机规范 · 基本结构 · Java堆(Heap) · Java栈(St ...

  8. 云端TensorFlow读取数据IO的高效方式

    低效的IO方式 最近通过观察PAI平台上TensoFlow用户的运行情况,发现大家在数据IO这方面还是有比较大的困惑,主要是因为很多同学没有很好的理解本地执行TensorFlow代码和分布式云端执行T ...

  9. CSS3 基础(1)——选择器详解

    CSS3选择器详解 一. 属性选择器 在CSS3中,追加了三个属性选择器分别为:[att*=val].[att^=val]和[att$=val],使得属性选择器有了通配符的概念. 选择器 示例 描述 ...

  10. linux 压缩解压打包工具大集合

    压缩.解压缩及归档工具有很多,今天小编就整理几个大家较为常用的. compress gzip  bzip2 xz zip tar cpio 一.压缩.解压工具 用法 压缩 工具 压缩后 压缩包格式 解 ...