秒杀超卖现象:在高并发下,多个线程并发更新库存,导致库存为负的情况。
我搜集了一些资料,整理了一下,秒杀可选方案主要有以下三种:
1.超卖原因
一个简单的订单表
create table orders (
sku_id int PRIMARY KEY,
count int
)
一个/buy接口
begin()
count = db.Query(`select count from orders where sku_id = '123'`)
if count < 0 {
fmt.Println("卖光了")
return ;
}
db.Exec(`update orders set count = count -1 where sku_id = '123'`)
commit()
由于sql 支持并行加上事务的隔离性,所以当多个事务并行时,select出来的值并不一定准确的,进而update之后的值也就不正确了。
方案一数据库悲观锁
数据库设置字段为无符号型
当并发超卖时直接报异常
通过捕获异常提示已经售空。
方案二:数据库悲观锁
采用排他锁
当用户同时到达更新操作,同时到达的用户一个个执行
在当前这个update语句commit之前,其他用户等待执行
解决方法:
begin()
update orders set count = count -1 where count > 0 and sku_id = '123'
commit()
这里是利用了update造成的行级锁,避免了超卖的问题。
优点:确保了线程安全。
缺点:高并发场景下会导致多个请求一直等待,数据库性能下降,系统的链接数上升,负载飙升,影响系统的平均响
发布者:admin,转转请注明出处:http://www.yc00.com/web/1754940910a5218128.html
评论列表(0条)