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;
}
}