Redis从入门到精通-Redis-事物和锁机制-超时和超卖问题解决
一、超卖问题

二、利用乐观锁淘汰用户,解决超卖问题。

三、代码
package com.atguigu; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.Transaction; import java.io.IOException; import java.util.List; /** * */ public class SecKill_redis_advance { public static void main(String[] args) { Jedis jedis =new Jedis("192.168.117.134",6379); System.out.println(jedis.ping()); jedis.close(); } //秒杀过程 public static boolean doSecKill(String uid,String prodid) throws IOException { //1 uid和prodid非空判断 if(uid == null && prodid == null){ return false; } //2 连接redis //通过连接池得到jedis对象 JedisPool jedisPoolInstance = JedisPoolUtil.getJedisPoolInstance(); Jedis jedis = jedisPoolInstance.getResource(); //3 拼接key // 3.1 库存key String kcKey="sk:"+prodid+":qt"; // 3.2 秒杀成功用户key String userKey="sk:"+prodid+":user"; //监视库存 加乐观锁 jedis.watch(kcKey); //4 获取库存,如果库存null,秒杀还没有开始 String kcVal = jedis.get(kcKey); if(kcVal == null){ System.out.println("秒杀还没有开始,请等待。"); jedis.close(); return false; } // 5 判断用户是否重复秒杀操作 Boolean sismember = jedis.sismember(userKey, uid); if(sismember){ System.out.println("已经秒杀过了,不能重复秒杀"); jedis.close(); return false; } //6 判断如果商品数量,库存数量小于1,秒杀结束 int intKcVal = Integer.parseInt(kcVal); if(intKcVal<=0){ System.out.println("秒杀结束"); jedis.close(); return false; } //7 秒杀过程 //使用事务 Transaction multi = jedis.multi(); //组队操作 multi.decr(kcKey); multi.sadd(userKey,uid); List<Object> result = multi.exec(); if(result == null && result.size() ==0){ System.out.println("事物中秒杀失败"); jedis.close(); return false; } System.out.println("秒杀成功"); return true; } }
四、测试
1、设置库存。

2、ab工具模拟测试
ab -n 1000 -c 100 -k -p /ab/postfile -T application/x-www-form-urlencoded http://192.168.10.1:8080/Seckill/doseckill


五、连接超时,使用连接池
package com.atguigu; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; public class JedisPoolUtil { private static volatile JedisPool jedisPool = null; private JedisPoolUtil() { } public static JedisPool getJedisPoolInstance() { if (null == jedisPool) { synchronized (JedisPoolUtil.class) { if (null == jedisPool) { JedisPoolConfig poolConfig = new JedisPoolConfig(); poolConfig.setMaxTotal(2000); poolConfig.setMaxIdle(32); poolConfig.setMaxWaitMillis(100*1000); poolConfig.setBlockWhenExhausted(true); poolConfig.setTestOnBorrow(true); // ping PONG jedisPool = new JedisPool(poolConfig, "192.168.117.134", 6379, 60000 ); } } } return jedisPool; } public static void release(JedisPool jedisPool, Jedis jedis) { if (null != jedis) { jedisPool.returnResource(jedis); } } }

浙公网安备 33010602011771号