1、什么是超卖
超卖就是卖出了超过预期数量的商品。
本来商家为了流量,准备拿出10件商品1折亏本出售,但是实际上卖出了200件,这下商家就亏大了。这就是超卖现象。
2、超卖解决方案
(1)方案一:设置数据库事务的隔离级别为Serializable
该隔离级别不允许事务并发执行,只能串行化执行,一个事务执行完才能执行下一个事务。
该方案确实可以解决超卖问题,但实际应用中却不可行,毕竟一个事务执行1秒,10万人就是10万秒,没有任何一个用户会愿意等这么长时间。
(2)方案二:在数据表上添加版本号字段
为数据表添加一个 lock_version字段,表示版本号。
执行更新前,先获取数据记录,得到该条记录版本号。
执行更新时,添加版本号做为where条件。
# 伪代码
开启事务;
1、到数据库查询该条记录(假设查询到的记录中版本号是18)
2、执行更新操作
update ... set lock_version = lock_version + 1 .... where lock_version = 18
if (执行成功) {
提交事务
} else {
回滚事务;
}
该方案解决超卖现象是可行的,但实际应用中,还是不建议使用,因为MySQL本身是基于磁盘的,性能是逃脱不了的问题。
(3)方案三:利用Redis防止超卖
从性能上来讲,Redis读写性能 2万/秒;MySQL读性能5千/秒,写性能3千/秒。
并且Redis基于内存缓存数据,虽然是单线程的NoSQL数据库,但采用的是非阻塞执行,因此其效率要远超MySQL。