redis实现分布式锁 商品秒杀lua脚本
2021/12/15 2:22:45
本文主要是介绍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;
}
}
这篇关于redis实现分布式锁 商品秒杀lua脚本的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-08阿里云Redis项目实战入门教程
- 2024-11-08阿里云Redis资料:新手入门与初级使用指南
- 2024-11-08阿里云Redis教程:新手入门及实用指南
- 2024-11-07阿里云Redis学习入门:新手必读指南
- 2024-11-07阿里云Redis学习入门:从零开始的操作指南
- 2024-11-07阿里云Redis学习:初学者指南
- 2024-11-06阿里云Redis入门教程:轻松搭建与使用指南
- 2024-11-02Redis项目实战:新手入门教程
- 2024-10-22Redis入门教程:轻松掌握数据存储与操作
- 2024-10-22Redis缓存入门教程:快速掌握Redis缓存基础知识