微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

redis实现分布式锁 商品秒杀lua脚本

redis.clients jedis 2.9.0 @Component public class RedisTest {
private static final String LOCK_SUCCESS = "OK";
private static final String SET_IF_NOT_EXIST = "NX";
private static final String SET_WITH_EXPIRE_TIME = "PX";
private static final Long RELEASE_SUCCESS = 1L;
private static final String UUIDREdis = UUID.randomUUID().toString();

// private static ShardedJedisPool pool;
// static {
// JedisPoolConfig config = new JedisPoolConfig();
// config.setMaxTotal(100);
// config.setMaxIdle(50);
// config.setMaxWaitMillis(3000);
// config.setTestOnBorrow(true);
// config.setTestOnReturn(true);
// // 集群
// JedisShardInfo jedisShardInfo1 = new JedisShardInfo(“192.168.31.30”, 6379);
// jedisShardInfo1.setPassword(“pg@123321”);
// List list = new LinkedList();
// list.add(jedisShardInfo1);
// pool = new ShardedJedisPool(config,list);
// }

//如果不是一步操作原子性 中间断掉无过期时间就可能死锁
public static boolean tryGetdistributedLock(Jedis jedis, String lockKey, String requestId, int expireTime) {
    String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
    if (LOCK_SUCCESS.equals(result)) {
        return true;
    }
    return false;
}

//不校验value锁的拥有者 会导致客户端都可以删除
public static boolean releasedistributedLock(Jedis jedis, String lockKey, String requestId) {
    String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
    Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));

    if (RELEASE_SUCCESS.equals(result)) {
        return true;
    }
    return false;
}

@postconstruct
public static void test(){
    Jedis jedis = new Jedis("192.168.31.30", 6379);
    jedis.auth("pg@123321");
    if(tryGetdistributedLock(jedis,"RedisTest-test",UUIDREdis,20*1000)){
        System.out.println("加锁成功");
        //数据库操作
        if(releasedistributedLock(jedis,"RedisTest-test",UUIDREdis)){
            System.out.println("解锁成功");
        }else {
            System.out.println("解锁失败");
        }
    }else{
        System.out.println("加锁失败");
    }
}


//set命令 sismember是否包含集合中
static String luaScript =
        "local userid=KEYS[1];\r\n" +
        "local prodid=KEYS[2];\r\n" +
        "local qtkey='sec:'..prodid..\":count\";\r\n" +
        "local usersKey='sec:'..prodid..\":user\";\r\n" +
        "local userExists=redis.call(\"sismember\",usersKey,userid);\r\n" +
        "if tonumber(userExists)==1 then \r\n" +
        "   return 2;\r\n" +
        "end\r\n" +
        "local num = redis.call(\"get\" ,qtkey);\r\n" +
        "if tonumber(num)<=0 then \r\n" +
        "   return 0;\r\n" +
        "else \r\n" +
        "   redis.call(\"decr\",qtkey);\r\n" +
        "   redis.call(\"sadd\",usersKey,userid);\r\n" +
        "end\r\n" +
        "return 1" ;



@postconstruct
public void test2(){
    Jedis jedis = new Jedis("192.168.31.30", 6379);
    jedis.auth("pg@123321");
    jedis.set("sec:2:count", "100");

    AtomicInteger atomicInteger = new AtomicInteger(0);
    while(true){
        boolean result = doSecKill(jedis,UUID.randomUUID().toString(),"2");
        if(result == false){
            break;
        }else{
            atomicInteger.incrementAndGet();
        }
    }
    System.out.println("result:"+atomicInteger.get());

}
public boolean doSecKill(Jedis jedis,String uid,String prodid) {

    String sha1 = jedis.scriptLoad(luaScript); //加入缓存
    Object result= jedis.evalsha(sha1, 2, uid,prodid);//那个脚本 几个参数

    String reString=String.valueOf(result);
    if ("0".equals( reString )  ) {
        System.err.println("已抢空!!");
        return false;
    }else if("1".equals( reString )  )  {
        System.out.println(uid + "抢购成功!!!!");
    }else if("2".equals( reString )  )  {
        System.err.println("该用户已抢过!!");
    }else{
        System.err.println("抢购异常!!");
    }

// JedisPollTool.distroy(jedisPool, jedis);
return true;

}

}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐