高并发下超卖问题及如何解决
主要思路是:
1. 首先在团购秒杀开始前将需要的物品库存信息放入缓存中
2. 使用锁来处理其并发请求
3. 将缓存中的数据同步到数据库。
我们此处使用redis作为缓存。
应用操作redis减库存的大体思路为:
1. 首先通过redis api监听相关物品的库存信息,在事务开启前保证该物品库存信息无人修改
2. 获取现有库存信息,判断库存不为0并且当前库存量大于等于订单所需数量
3. 满足上述2的话则进行扣除操作
4. 如果在1的过程中有别人更新了该物品库存信息版本,则重试
5. 直到库存为0或者剩余库存不满足当前订单扣除数量退出
具体代码如下:
public void secondBuyProduct(Jedis jedis, String stockId, int orders) {
while (true) {
try {
jedis.watch(stockId);
int prdNum = Integer.parseInt(jedis.get(stockId));
if (prdNum > 0 && prdNum - orders >= 0)) {
Transaction transaction = jedis.multi();
transaction.set(stockId, String.valueOf(prdNum - orders));
List<Object> res = transaction.exec();
if (res != null && !res.isEmpty()) {
System.out.println("抢购成功!");
break;
}
} else {
System.err.println("被抢光了!");
break;
}
} catch (Exception e) {
System.err.println("抢购出错:" + e.toString());
e.printStackTrace();
} finally {
jedis.unwatch();
}
}
}