秒杀系统设计(防止超卖)

helei 2020-7-28 937 7/28

共享锁(S):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。

排他锁(X):允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的共享读锁和排他写锁。

按照正常的购买流程:查询商品库存,库存大于0时,生成订单,去库存。如果出现并发,导致在查询商品库存的时候,库存会一直出现大于0的情况,出现超卖现象。

基于mysql的事务和锁实现方式:

1:开启事务

2:查询库存,并显示的设置写锁(排他锁):SELECT * FROM table_name WHERE … FOR UPDATE

3:生成订单

4:去库存,隐示的设置写锁(排他锁):UPDATE goods SET counts = counts – 1 WHERE id = 1

5:commit,释放锁

注意:

如果不开启事务,第二步即使加锁,第一个会话读库存结束后,变会释放锁,第二个会话仍有机会在去库存前读库存,出现超卖。

如果开启事务,第二步不加锁,第一个会话读库存结束后,第二个会话容易出现【脏读】,出现超卖。

即加事务,又加读锁:开启事务,第一个会话读库存时加读锁,并发时,第二个会话也允许获得读库存的读锁,但是在第一个会话执行写操作时,写锁便会等待第二个会话的读锁,第二个会话执行写操作时,写锁便会等待第一个会话的读锁,出现死锁

即加事务,又加写锁:第一个会话读库存时加写锁,写锁会阻止其它事务的读锁和写锁。直到commit才会释放,允许第二个会话查询库存,不会出现超卖现象。

乐观锁

悲观锁(读锁(共享锁) lock in share mode,写锁(排它锁)FOR UPDATE

thinkphp5 事务锁

- THE END -

helei

7月28日17:34

最后修改:2020年7月28日
0

非特殊说明,本博所有文章均为博主原创。