level 11
为啦防止用户重复购买,需要判断用户是否已经购买过啦,但是如果同一时间一个用户发出两次请求,这时判断都是未购买,这种问题怎么办
2019年01月06日 06点01分
1
level 9
规定时间内只能发出一次请求,其他直接返回。。。,csdn秒杀问题总结很多
2019年01月06日 08点01分
2
level 11
@Override//保存秒杀订单
public void saveSeckillOrder(Long seckillGoodsId, String userId) {
//有请求下单的任务,就把排队人数加一
redisTemplate.boundValueOps("SECKILL_COUNT_ORDER_QUEUE").increment(1);
//判断该用户是否已经秒杀过啦
Boolean member = redisTemplate.boundSetOps("SECKILL_PAY_LOG" + seckillGoodsId).isMember(userId);
if (member) {
throw new RuntimeException("请先支付,不允许重复秒杀");
}
//解决超卖问题 task里leftpush 这里rightpop [3,2,1]
Object o = redisTemplate.boundListOps("SECKILL_GOODS_QUEUE" + seckillGoodsId).rightPop();
if (o == null) {
throw new RuntimeException("被抢光啦");
}
TbSeckillGoods seckill_goods = (TbSeckillGoods) redisTemplate.boundHashOps("SECKILL_GOODS").get(seckillGoodsId);
//判断是否有库存
if (seckill_goods.getStockCount() <= 0 || seckill_goods == null) {
throw new RuntimeException("被抢光啦");
}
//当排队人数过多时,提示
Long count_order_queue = redisTemplate.boundValueOps("SECKILL_COUNT_ORDER_QUEUE").size();
if (count_order_queue > (seckill_goods.getStockCount() + 10)) {
throw new RuntimeException("当前人数过多");
}
//将多线程操作mysql任务放入redis
redisTemplate.boundListOps("SECKILL_ORDER_QUEUE").leftPush(new UserIdAndSeckillGoodsId(userId, seckillGoodsId));
executor.execute(createOrder);
}
2019年01月06日 08点01分
3
level 1
使用同步,在将用户加入购买列表的代码放到同步块里面执行,加入前先判断购买列表里有没有该用户
synchronized(this.getClass){
Boolean member = redisTemplate.boundSetOps("SECKILL_PAY_LOG" + seckillGoodsId).isMember(userId);
if (member) {
throw new RuntimeException("请先支付,不允许重复秒杀");
}
//将多线程操作mysql任务放入redis
redisTemplate.boundListOps("SECKILL_ORDER_QUEUE").leftPush(new UserIdAndSeckillGoodsId(userId, seckillGoodsId));
executor.execute(createOrder);
}
2019年01月06日 13点01分
5
同步代码块好像不太好,网上的资料好像是基于redis的watch乐观锁,不太懂
2019年01月06日 13点01分
@朕不灭 乐观锁也行,不过将同步代码的范围缩到最小,让锁竞争都处于轻量级其实比乐观锁性能要好
2019年01月06日 13点01分
@朕不灭 都忘了你要解决的是防止同一个用户重复提交,乐观锁无法实现
2019年01月06日 16点01分
level 8
直接在表里加一个字段和userid关联代表是否购买,执行购买的时候sql必须加上where 是否购买=否
2019年01月07日 04点01分
6
level 1
分布式锁呀,下单时候需要加锁,你可以理解为下单必须是串行的,加锁期间判断这个用户是不是秒杀过,秒杀
2019年05月30日 06点05分
9