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

  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. 快速搭建MySQL复制集

    快速搭建MySQL复制集 1 环境说明 MySQL版本 5.6 basedir :/u01/my3306 #MySQL软件目录 数据目录 :/u01/mysql/[实例名]/data 日志目录 :/u ...

  2. SpringBoot上传任意文件功能的实现

    一.pom文件依赖的添加 <dependencies> <dependency> <groupId>org.springframework.boot</gro ...

  3. Github上比较流行的PHP扩展库项目

    这里列出比较常用的PHP开源扩展库项目: swoole, C扩展实现的PHP异步并行网络通信框架,可以重新定义PHP.过去PHP只能做Web项目,现在有了Swoole.任意服务器端程序都可以用PHP来 ...

  4. Go语言学习笔记(六)net

    加 Golang学习 QQ群共同学习进步成家立业工作 ^-^ 群号:96933959 net import "net" net包提供了可移植的网络I/O接口,包括TCP/IP.UD ...

  5. Python使用openpyxl读写excel文件

    Python使用openpyxl读写excel文件 这是一个第三方库,可以处理xlsx格式的Excel文件.pip install openpyxl安装.如果使用Aanconda,应该自带了. 读取E ...

  6. wamp问题:关于另个php.ini文件的”…

    一.现象解说 修改从图表打开的php.ini文件,重启apache后,我们的问题没有解决... 二.解决方法 1.php.ini的位置 wamp/apache2/bin/php.ini wamp/ph ...

  7. python 密码学编程

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

  8. 对于JavaScript中this关键字的理解

    这是我第二遍学this了,第一遍学的懵懵的.this指哪里都是凭我一个男人的直觉然后控制台输出看看对不对. 刚查了书.博客.视频.理解差不多了.毕竟菜鸡me: 一.首先介绍下什么是this this是 ...

  9. Canvas: 优雅的代码作图系列:中国国旗

    Canvas: 优雅的代码作图系列:中国国旗 有很多个这练手的,好的差的都有.这次,我演示下用极客的代码,画出最标准的中国国旗,并详细说明代码是怎么写出来的. 绘制规范: 一.严格按照绘制说明: 二. ...

  10. 1 Acid burn ★ Nag,Name/Serial,Serial

    无花无壳爆破 仅允许非商业转载,转载请注明出处