redis 批量加锁
2016-04-25 10:57
489 查看
/* * redis 多数据同时上锁,添加超时异常 * */ public void lockKeys(List<String> keys) { //上锁失败时,还原使用的Map Map<String,Long>keyValues = new HashMap<String,Long>(); //等待标记 boolean success = true; //等待周期 int outTime = 0; //循环所有key上锁 while(success) { //遍历所有key 上锁情况 : 3· /*1·未上锁(包括超时),key加锁; * 2·上锁,等待其他解锁; * 3·超时,但是其他没有解锁,属于异常处理 * */ int index = 0; long lastResult=0 ; for( ; index< keys.size() ;index++) { String key = keys.get(index); lastResult = this.lock(key);//上锁,记录返回值 keyValues.put(key, lastResult);//添加还原记录 if(lastResult != -1 ) //正常继续加锁,超时解锁继续加锁 { if(index==(keys.size()-1)) //判断是否循环完成,上锁成功 success = true; continue; } else //其他已经加锁,打断等待并还原原来锁状态 { success = false; break; } } if(!success) { if(outTime<20) //等待 { try { Jedis jedis = this.jedisPool.getResource(); //等待之前还原锁 jedis.select(lockDB); for(int i = 0; i<=index;i++) { String key = keys.get(i); long value = keyValues.get(key); if(value==0) { jedis.del(key); }else { jedis.getSet(key, String.valueOf(value)); } } jedis.close(); Thread.sleep(100);///等待 outTime++;//等待超时记录 } catch (InterruptedException e) { e.printStackTrace(); } }else { throw new DDDException("批量上锁排队信息出错"); } } } } /* * redis 数据上锁 成功return 0 失败 return -1 超时return oldvalue * */ private long lock(String key) { // 1. 通过SETNX试图获取一个lock long success = -1; Jedis jedis = this.jedisPool.getResource(); jedis.select(lockDB); long value = System.currentTimeMillis() +this.lockExpired+ 1; long acquired = jedis.setnx(key, String.valueOf(value)); //SETNX成功,则成功获取一个锁 if (acquired == 1) success = 0; //SETNX失败,说明锁仍然被其他对象保持,检查其是否已经超时 else { long oldValue = Long.valueOf(jedis.get(key)); //超时 if (oldValue < System.currentTimeMillis()) { String getValue = jedis.getSet(key, String.valueOf(value)); // 获取锁成功 if (Long.valueOf(getValue) == oldValue) success = oldValue; /* * redis 多数据同时上锁,添加超时异常 * */ public void lockKeys(List<String> keys) { //上锁失败时,还原使用的Map Map<String,Long>keyValues = new HashMap<String,Long>(); //等待标记 boolean success = true; //等待周期 int outTime = 0; //循环所有key上锁 while(success) { //遍历所有key 上锁情况 : 3· /*1·未上锁(包括超时),key加锁; * 2·上锁,等待其他解锁; * 3·超时,但是其他没有解锁,属于异常处理 * */ int index = 0; long lastResult=0 ; for( ; index< keys.size() ;index++) { String key = keys.get(index); lastResult = this.lock(key);//上锁,记录返回值 keyValues.put(key, lastResult);//添加还原记录 if(lastResult != -1 ) //正常继续加锁,超时解锁继续加锁 { if(index==(keys.size()-1)) //判断是否循环完成,上锁成功 success = true; continue; } else //其他已经加锁,打断等待并还原原来锁状态 { success = false; break; } } if(!success) { if(outTime<20) //等待 { try { Jedis jedis = this.jedisPool.getResource(); //等待之前还原锁 jedis.select(lockDB); for(int i = 0; i<=index;i++) { String key = keys.get(i); long value = keyValues.get(key); if(value==0) { jedis.del(key); }else { jedis.getSet(key, String.valueOf(value)); } } jedis.close(); Thread.sleep(100);///等待 outTime++;//等待超时记录 } catch (InterruptedException e) { e.printStackTrace(); } }else { throw new DDDException("批量上锁排队信息出错"); } } } } /* * redis 数据上锁 成功return 0 失败 return -1 超时return oldvalue * */ private long lock(String key) { // 1. 通过SETNX试图获取一个lock long success = -1; Jedis jedis = this.jedisPool.getResource(); jedis.select(lockDB); long value = System.currentTimeMillis() +this.lockExpired+ 1; long acquired = jedis.setnx(key, String.valueOf(value)); //SETNX成功,则成功获取一个锁 if (acquired == 1) success = 0; //SETNX失败,说明锁仍然被其他对象保持,检查其是否已经超时 else { long oldValue = Long.valueOf(jedis.get(key)); //超时 if (oldValue < System.currentTimeMillis()) { String getValue = jedis.getSet(key, String.valueOf(value)); // 获取锁成功 if (Long.valueOf(getValue) == oldValue) success = oldValue; // 已被其他进程捷足先登了 else success = -1; } //未超时,则直接返回失败 else success = -1; } // this.jedisPool.returnResource(jedis); jedis.close(); return success; } // 已被其他进程捷足先登了 else success = -1; } //未超时,则直接返回失败 else success = -1; } // this.jedisPool.returnResource(jedis); jedis.close(); return success; }
相关文章推荐
- redis之事物(基础篇)
- Redis 知识
- Redis-stat的安装与使用
- Redis键时间老化的测试
- 【.Net】文件并发(日志处理)--队列--Redis+Log4Net
- windows下的redis 2.x 配置
- redis性能问题排查
- 关于Redis info的参数总结
- redis的基本类型及操作命令
- Linux下php安装Redis扩展
- Redis安装部署配置说明
- PHP Startup redis: Unable to initialize module
- Redis数据类型
- Redis配置
- redis 集群
- redis 数据持久化 详细说明
- Redis源码分析——链表
- redis 数据持久化
- Redis源码分析——SDS
- Redis源码解析(1)