高并发中的超卖问题

高并发中的超卖问题

高并发中的超卖问题

1.在sql加上判断防止数据变为负数

​ update goods set num = num - 1 WHERE id = 1001 and num > 0

​ 就算很多线程同时读到了这个num = 1,但是都只有一个线程减库存成功,其余的全部失败。

因为这是MySQL中的排它锁起了作用

​ 排它锁又称为写锁,简称X锁,就是不能与其他锁并存,如果一个事务获取了一个数据行的排它锁,其他事务就不能再获取该行的其他锁。

2.利用CAS原理,加版本号

1 select version from goods WHERE id= 1001
2 update goods set num = num - 1, version = version + 1 WHERE id= 1001 AND num > 0 AND version = @version(上面查到的version);

​ 假设此时version = 100, num = 1; 100个线程进入到了这里,同时他们select出来版本号都是version = 100。

然后直接update的时候,只有其中一个先update了,同时更新了版本号。

​ 那么其他99个在更新的时候,会发觉version并不等于上次select的version,就说明version被其他线程修改过了。那么我就放弃这次update

3.利用Redis单线程预减库存

​ 比如商品有100件。那么我在redis存储一个k,v。例如 每一个用户线程进来,key值就减1,等减到0的时候,全部拒绝剩下的请求。那么也就是只有100个线程会进入到后续操作。所以一定不会出现超卖的现象

4.引入队列

​ 将所有写DB操作在单队列中排队,完全串行处理。当达到库存阀值的时候就不在消费队列,并关闭购买功能。

5.数据库加唯一索引防止用户重复购买

发布于 2020-07-30 21:59