超卖问题

大彬
大约 1 分钟

超卖问题

先到数据库查询库存,在减库存。不是原子操作,会有超卖问题。

通过加排他锁解决该问题。

  • 开始事务。
  • 查询库存,并显式的设置排他锁:SELECT * FROM table_name WHERE … FOR UPDATE
  • 生成订单。
  • 去库存,update会隐式的设置排他锁:UPDATE products SET count=count-1 WHERE id=1
  • commit,释放锁。

也可以通过乐观锁实现。使用版本号实现乐观锁。

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

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

那么其他99个在更新的时候,会发觉version并不等于上次select的version,就说明version被其他线程修改过了,则放弃此次update,重试直到成功。

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