深浅模式
超时和超卖问题解决
超卖问题

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

代码
shell
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;
}
}继续增加并发测试
设置库存

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

连接超时,使用连接池
shell
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);
}
}
}