您的位置:首页 > 数据库 > Redis

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: