Jedis结合setNX方法实现分布式锁

public boolean lock(String key, int exprie) {
try {
exprie = exprie <= 0 ? 60 : exprie;
String value = JsonUtil2.obj2String(createMeta(exprie));
String lockKey = this.getLockKeyPrev() + key;
String result=this.setNX(lockKey, value,"EX",exprie);
if (result!=null && result.equals("OK")) {
LOGGER.info("Get redis lock success, key =" + lockKey);
return true;
}
Object obj = this.get(lockKey);
if (obj==null) {
this.delete(lockKey);
LOGGER.info("Redis unlock success ,key = " + lockKey);
Thread.sleep(1000);
value = JsonUtil2.obj2String(createMeta(exprie));
String result1=this.setNX(lockKey, value,"EX",exprie);
if (result1!=null && result1.equals("OK")) {
this.expire(lockKey, exprie);
LOGGER.info("Get redis lock success, key =" + lockKey);
return true;
} else {
LOGGER.warn("Get redis lock fail, key =" + lockKey);
return false;
}
}
value = (String)obj;
LockModel model = JsonUtil2.getObjectMapper().readValue(value, LockModel.class);
if (model.isLose()) {// 已经超时
this.delete(lockKey);
value = JsonUtil2.obj2String(createMeta(exprie));
String result2=this.setNX(lockKey, value,"EX",exprie);
if (result2!=null && result2.equals("OK")) {
this.expire(lockKey, exprie);
LOGGER.info("Get redis lock success, key =" + lockKey);
return true;
} else {
LOGGER.warn("Get redis lock fail, key =" + lockKey);
return false;
}
}
LOGGER.warn("Get redis lock fail, key =" + lockKey);
return false;
} catch (Exception ex) {
ex.printStackTrace();
LOGGER.error(ex.getMessage());
return true;
}
} public void unlock(String key) {
String lockKey = this.getLockKeyPrev() + key;
try {
delete(lockKey);
} catch (Exception ex) {
LOGGER.error(ex.getMessage());
}
LOGGER.info("Redis unlock success ,key = " + lockKey);
} private LockModel createMeta(int exprie) {
LockModel meta = new LockModel();
meta.setExpireTime(exprie);
meta.setLockTime(System.currentTimeMillis());
return meta;
} public String getLockKeyPrev() {
return "lock:";
} /**
* 设置key
* 需要传入key是否不存存在
*
* @param key 键
* @param value 值
* @param expx EX/PX 值只能取EX或者PX,代表数据过期时间的单位,EX代表秒,PX代表毫秒
* @param interval 过期时间,单位是expx所代表的单位。
* @return SET 在设置操作成功完成时,才返回 OK 。
* 如果设置了 NX 或者 XX ,但因为条件没达到而造成设置操作未执行,那么命令返回空批量回复(NULL Bulk Reply)
*/
public String setNX(String key, Object value, String expx, long interval) {
Jedis jedis = MyRedisPool.getJedis();
String result = "";
try {
result = jedis.set(key, String.valueOf(value), "NX", expx, interval);
} catch (Exception e) {
e.printStackTrace();
} finally {
MyRedisPool.returnResource(jedis);
}
return result;
} /**
* 删除给定的一个或多个 key 。
* 不存在的 key 会被忽略。
*
* @param key 键
* @return 被删除 key 的数量。
*/
public Long delete(String key) {
Jedis jedis = MyRedisPool.getJedis();
Long result = 0L;
try {
result = jedis.del(key);
} catch (Exception e) {
e.printStackTrace();
} finally {
MyRedisPool.returnResource(jedis);
}
return result;
}
/**
* 为给定 key 设置生存时间,当 key 过期时(生存时间为 0 ),它会被自动删除。
* 可以对一个已经带有生存时间的 key 执行 EXPIRE 命令,新指定的生存时间会取代旧的生存时间。
*
* @param key
* @param interval
* @return 设置成功返回 1 。
* 当 key 不存在或者不能为 key 设置生存时间时(比如在低于 2.1.3 版本的 Redis 中你尝试更新 key 的生存时间),返回 0 。
*/
public Long expire(String key, int interval) {
Jedis jedis = MyRedisPool.getJedis();
Long result = 0L;
try {
result = jedis.expire(key, interval);
} catch (Exception e) {
e.printStackTrace();
} finally {
MyRedisPool.returnResource(jedis);
}
return result;
}
/**
* 返回 key 所关联的字符串值
* 如果 key 不存在那么返回特殊值 nil 。
*
* @param key
* @return 当 key 不存在时,返回 nil ,否则,返回 key 的值。
* 如果 key 不是字符串类型,那么返回一个错误。
*/
public Object get(String key) {
Jedis jedis = MyRedisPool.getJedis();
Object o = null;
try {
o = jedis.get(key);
} catch (Exception e) {
e.printStackTrace();
} finally {
MyRedisPool.returnResource(jedis);
}
return o;
}

  

Redis实现分布式锁1的更多相关文章

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

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

  2. 用Redis构建分布式锁-RedLock(真分布)

    在不同进程需要互斥地访问共享资源时,分布式锁是一种非常有用的技术手段. 有很多三方库和文章描述如何用Redis实现一个分布式锁管理器,但是这些库实现的方式差别很大,而且很多简单的实现其实只需采用稍微增 ...

  3. 用Redis实现分布式锁 与 实现任务队列(转)

    这一次总结和分享用Redis实现分布式锁 与 实现任务队列 这两大强大的功能.先扯点个人观点,之前我看了一篇博文说博客园的文章大部分都是分享代码,博文里强调说分享思路比分享代码更重要(貌似大概是这个意 ...

  4. 利用多写Redis实现分布式锁原理与实现分析(转)

    利用多写Redis实现分布式锁原理与实现分析   一.关于分布式锁 关于分布式锁,可能绝大部分人都会或多或少涉及到. 我举二个例子:场景一:从前端界面发起一笔支付请求,如果前端没有做防重处理,那么可能 ...

  5. Redis实现分布式锁

    http://redis.io/topics/distlock 在不同进程需要互斥地访问共享资源时,分布式锁是一种非常有用的技术手段. 有很多三方库和文章描述如何用Redis实现一个分布式锁管理器,但 ...

  6. 基于redis的分布式锁

    <?php /** * 基于redis的分布式锁 * * 参考开源代码: * http://nleach.com/post/31299575840/redis-mutex-in-php * * ...

  7. Redis实现分布式锁与任务队列

    Redis实现分布式锁 与 实现任务队列 这一次总结和分享用Redis实现分布式锁 与 实现任务队列 这两大强大的功能.先扯点个人观点,之前我看了一篇博文说博客园的文章大部分都是分享代码,博文里强调说 ...

  8. 使用Redis实现分布式锁

    在天猫.京东.苏宁等等电商网站上有很多秒杀活动,例如在某一个时刻抢购一个原价1999现在秒杀价只要999的手机时,会迎来一个用户请求的高峰期,可能会有几十万几百万的并发量,来抢这个手机,在高并发的情形 ...

  9. 基于Redis实现分布式锁(1)

    转自:http://blog.csdn.net/ugg/article/details/41894947 背景在很多互联网产品应用中,有些场景需要加锁处理,比如:秒杀,全局递增ID,楼层生成等等.大部 ...

  10. redis咋么实现分布式锁,redis分布式锁的实现方式,redis做分布式锁 积极正义的少年

    前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁.虽然网上已经有各种介 ...

随机推荐

  1. $.ajax()——超时设置,增加 loading 提升体验

    前端发送Ajax请求到服务器,服务器返回数据这一过程,因原因不同耗时长短也有差别,且这段时间内页面显示空白.如何优化这段时间内的交互体验,以及长时间内服务器仍未返回数据这一问题,是我们开发中不容忽视的 ...

  2. [CentOS] 7 不执行文件 /etc/rc.d/rc.local

    chmod 0755 /etc/rc.local systemctl enable rc-local.service --now systemctl restart rc-local.service

  3. Oauth2.0 整合springCloud的Zuul 解决关键BUG 报错信息:Principal must not be null

    不清楚Oauth2.0 的 可以查看我前几篇博文 2018.4.8 补充 我出现这个原因:是我在资源服务器使用了 如下图所示 Principal Oauth2.0 提供的获取用户信息的方法 使其找到相 ...

  4. python基础知识梳理----5dict 字典的应用

    内容简介: 1:字典简介 2:字典的增删该查 3:字典嵌套 1: 字典(dict)是python中唯一的一个映射类型.他是以{ }括起来的键值对组成. 在dict中key是唯一的. 在保存的时候, 根 ...

  5. python里有意思的文件查找glob模块

    python标准库之glob介绍 glob 文件名模式匹配,不用遍历整个目录判断每个文件是不是符合. 1.通配符 星号(*)匹配零个或多个字符 import glob for name in glob ...

  6. 汉诺塔的python 动画演示

    1.简介 古代有一座汉诺塔,塔内有3个座A.B.C,A座上有n个盘子,盘子大小不等,大的在下,小的在上,如图所示.有一个和尚想把这n个盘子从A座移到C座,但每次只能移动一个盘子,并且自移动过程中,3个 ...

  7. DB2 Package Issues and Solution

    Client 从 10.1 升级到11.1之后,而server端的DB 是10.1 版本,当客户执行sql语句时候报错: select * from ebcc.eol_item_info where ...

  8. spring boot快速入门 2 :属性配置

    属性配置:在application.properties中配置 第一步:配置端口号和项目名 并启动 第二步:在浏览器查看请求 第二种配置方式: 在application.yml中配置.(较为常用) 注 ...

  9. 如何为 Go 设计一个通用的日志包

    需求 一个通用的日志包,应该满足以下几个需求: 兼容 log.Logger,标准库大量使用了 log.Logger 作为其错误内容的输出通道,比如 net/http.Server.ErrorLog,所 ...

  10. android开发之提高应用启动速度_splash页面瞬间响应_避免APP启动闪白屏

    Application和Activity中的onCreate都进行了优化,基本没有耗时操作,但是启动应用之后还是会闪现一下白色背景,然后才进入Splash页面,对比了一下QQ.微信.微博等客户端,点击 ...