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

  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. jdk配置java_home的两种方式

    在开发java项目的时候,要先安装jdk,安装完jdk之后我们要配置环境变量.今天说一下java home环境变量. 配置环境变量有两种方式,一种就是在计算机的环境变量里面配置.这个是很简单的.如果你 ...

  2. 人工智能(AI)库TensorFlow 踩坑日记之二

    上次 踩坑日志之一 遗留的问题终于解决了,所以作者(也就是我)终于有脸出来写第二篇了. 首先还是贴上 卷积算法的示例代码地址 :https://github.com/tensorflow/models ...

  3. HDU - 3853

    LOOPS Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 125536/65536 K (Java/Others)Total Sub ...

  4. 如何将R包安装到自定义路径

    参考  设置环境变量R_LIBS将R包安装到自定义路径   实际上是可以解决问题的, #环境变量完成以后,启动(重启)R,运行 .libPaths() 加载R包时,发现路径仍然未变成自定义的. 那么参 ...

  5. 最短路之Bellman-Ford算法

    说明: Dijkstra算法是处理单源最短路径的有效算法,但它局限于边的权值非负的情况,若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的. 这时候,就需要使用其他的算法 ...

  6. 无法远程连接服务器上的mysql

    使用mysql管理工具连接服务器删过得mysql,显示连接被拒绝,但是在服务器上是可以登录mysql的. 无法远程连接通常以下几种情况: 首先,关闭mysql.        service mysq ...

  7. centos 系统常用命令

    一:查看cpu信息more /proc/cpuinfo | grep "model name" grep "model name" /proc/cpuinfo ...

  8. AIX安装恢复oracle问题-内存不足

    AIX安装恢复oracle问题-----------------------2013/10/19 oracle 安装后后,进行rman恢复数据库时,启动不了dummy实例,报内存不足   RMAN&g ...

  9. OC版贪吃蛇

    昨天写了一个js版贪吃蛇,今天突然想写一个OC版的,来对比一下两种语言的区别 oc版功能,适配所有尺寸iphone,可暂停,可设置地图和蛇的比例,可加速 对比一下会发现js版的相对OC版的会简单一些, ...

  10. css3类选择器之结合元素选择器和多类选择器

    css3类选择器之结合元素选择器和多类选择器用法: <!DOCTYPE html> <html lang="en"> <head> <me ...