redis锁

拓展 ycgwl-cache RedisStorage

/**
     * 如果不存在则 写入缓存并设置过期时间
     * @param key
     * @param value
     * @param expire
     * @return
     */
    public synchronized Long setnx(String key, V value,int expire) {
        Jedis j = null;
        String svalue = JsonUtils.toJsonString(value);
        boolean borrowOrOprSuccess = true;

        try {
            j = this.client.getResource();
            Long setnx = j.setnx(key, svalue);
            j.expire(key, expire);

            return setnx;

        } catch (JedisException var10) {
            borrowOrOprSuccess = false;
            if (j != null) {
                this.client.returnBrokenResource(j);
            }

            LOG.error(var10.getMessage(), "EXCEPTION", var10);
        } finally {
            if (borrowOrOprSuccess) {
                this.client.returnResource(j);
            }

        }
        return 0L;
    }
 

框架 redis包 添加 RedisLock


package lock.lock;

import com.ycgwl.cache.storage.RedisStorage;

import java.util.Random;


public class RedisLock {

//纳秒和毫秒之间的转换率
public static final long MILLI_NANO_TIME = 1000 * 1000L;

//表示被锁定的 value 值
public static final String LOCKED = "TRUE";

public static final Random RANDOM = new Random();

//reids key
private String key;

//封装的操作redis的工具
private RedisStorage storage;

//是否锁定成功
private boolean lock = true;

//尝试获取锁的时间上限 毫秒
public static Long TRY_LOCK_TIME_OUT_MILLI_SECOND=2000l;
//自动失效时间 秒
public static int EXPIRE_SECOND=100;


/**
*
* @param purpose key的前缀
* @param key 一般都是数据的id
* @param storage redis客户端
*/
public RedisLock(String purpose, String key, RedisStorage storage){
this.key = purpose + "_" + key + "_lock";
this.storage = storage;
}

/**
* 默认 轮询尝试2秒 100秒失效
* @return
*/
public boolean lock(){
return this.lock(TRY_LOCK_TIME_OUT_MILLI_SECOND,EXPIRE_SECOND);
}

/**
* 加锁
* 使用方式为:
* lock();
* try{
* executeMethod();
* }finally{
* unlock();
* }
* @param timeout timeout的时间范围内轮询锁 纳秒
* @param expire 设置锁超时时间 秒
* @return 成功 or 失败
*/
public boolean lock(long timeout,int expire){

//获取当前纳秒级时间
long nanoTime = System.nanoTime();

//超时时间转纳秒
timeout *= MILLI_NANO_TIME;
try {
//在timeout的时间范围内不断尝试写入锁
while (System.nanoTime() - nanoTime < timeout) {
//锁不存在的话,设置锁并设置锁过期时间,即加锁
if (this.storage.setnx(this.key, LOCKED,expire) == 1) {
//设置锁过期时间是为了在没有释放锁的情况下锁过期后消失,不会造成永久阻塞
this.lock = true;
return this.lock;
}
//短暂休眠,避免可能的活锁
Thread.sleep(3, RANDOM.nextInt(30));
}
} catch (Exception e) {
throw new RuntimeException("获取锁失败",e);
}
return false;
}

/**
* 解锁
*/
public void unlock() {
try {
if(this.lock){
storage.remove(key);//直接删除
}
} catch (Throwable e) {
throw new RuntimeException("删除锁失败",e);
}
}

}
 

新添加加锁接口

    @Resource
    private RedisStorage storage;

    @Override
    public void updateOrderByLock(Long id){
        RedisLock redisLock = new RedisLock("BaseSiteEntity_SiteId", id + "", this.storage);
        boolean result = redisLock.lock();
        //取锁失败
        if(!result){
            throw new RuntimeException("id:"+id+" 获取锁失败");
        }
        try{
            //执行方法
             updateOrderBy(id);
        }finally{
            //释放锁
            redisLock.unlock();
        }

    }

 其他  http://www.cnblogs.com/zfzf1/p/7768211.html

原文地址:https://www.cnblogs.com/zfzf1/p/7773817.html