隐藏页面特效

秒杀案例设计

1|0存入redis中的设计


商品库存 key: sk:prodid:qt string: 剩余个数 秒杀成功者清单 key: sk:prodid:user set: 成功者的user_id 成功者的user_id 成功者的user_id

2|0代码实现


public static boolean doSecKill(String uid,String prodid) throws IOException{ //拼接向redis中保存库存和秒杀成功人员名单的key String kcKey = "sk:" + prodid + ":qt"; String userKey = "sk:" + prodid + ":user"; //创建Jredis连接池对象 JedisPool jedisPoolInstance = JedisPoolUtil.getJedisPoolInstance(); Jedis jedis = jedisPoolInstance.getResource(); //添加乐观锁 jedis.watch(kcKey); //获取库存 String count = jedis.get(kcKey); //判断库存的数量 if("0".equals(count)){ //证明已经秒完 System.err.println("已经秒完"); JedisPoolUtil.release(jedisPoolInstance.jedis); return false; } //添加事务 Transaction multi = jedis.multi(); //有库存的情况下需要进行以下操作 //将库存减1 multi.decr(kcKey); //保存秒杀成功者的名单 multi.sadd(userKey, uid); //执行 List<Object> exec = multi.exec(); if(exec == null || exec.size() == 0){ System.err.println("秒杀失败"); JedisPoolUtil.release(jedisPoolInstance.jedis); return false; } System.out.println("秒杀成功!!"); return true; }

3|0利用lua脚本解决超卖和库存遗留问题


local userid=KEYS[1]; local userid=KEYS[2]; local qtkey="sk:"..prodid..":qt"; local usersKey="sk:"..prodid..":user"; local userExists=redis.call("sismember",usersKey,userid); if tonumber(userExists)==1 then return 2; end local num=redis.call("get", qtkey); if tonumber(num) <=0 then return 0; else redis.call("decr", qtkey); redis.call("sadd",usersKey,userid); end return 1;

4|0代码实现


public static boolean doSecKill(String uid,String prodid) throws IOException{ JedisPool jedispool = JedisPoolUtil.getJedisPoolInstance(); Jedis jedis = jedispool.getResource(); String sha1 = jedis.scriptLoad(secKillScript); Object result = jedis.evalsha(sha1, 2, uid, prodid); String reString =String.valueOf(result); if ("0".equals(reString)){ System.err.println("已抢空"); } else if("1".equals(reString)){ System.out.println("抢购成功"); }else if("2".equals(reString)){ System.err.println("该用户已抢过"); }else{ System.err.println("抢购异常"); } jedis.close(); return true; } # secKillScript staic String secKillScript = "local userid=KEYS[1];\r\n" + "local userid=KEYS[2];\r\n" + "local qtkey='sk:'..prodid..\":qt\";\r\n" + "local usersKey='sk:'..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;"

__EOF__

本文作者404 Not Found
本文链接https://www.cnblogs.com/weiweivip666/p/17538221.html
关于博主:可能又在睡觉
版权声明:转载请注明出处
声援博主:如果看到我睡觉请喊我去学习
posted @   我在路上回头看  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
历史上的今天:
2021-07-09 vscode配置远程开发环境
2019-07-09 如何需求分析和编写测试用例
点击右上角即可分享
微信分享提示