一(直接在数据库中扣减库存)
前期分析:
*在多节点部署或者多线程执行时,同一个时间可能有多个线程更新相同数据,产生冲突。解决这种问题就可以使用锁来解决!
*乐观锁和悲观锁等都是锁的实现方式
通过乐观锁机制来避免超卖!
乐观锁:
乐观锁,不会发生并发抢占资源,只有在提交操作的时候检查是否违反数据完整性。只能防止脏读后数据的提交,不能解决脏读。(暂时采取)
排他锁:
虽然排他锁(for update)可以解决超卖!但是在每次select的时候加上了排它锁,每次select操作都会被堵塞,并发性能大大降低(不用)
我们这里来使用版本标识来确定读到的数据与提交时的数据是否一致。提交后修改版本标识,不一致时可以采取丢弃和再次尝试的策略。在商品表中建立一个version字段,某个抢购商品的库存为10,在高并发下,必然会导致多个用户拿到的库存和version都一模一样。因此当A用户扣减商品库存后,则需要将商品表中的version加1,当第B用户扣减库存时,由于version不匹配,发起重新查询并扣库存直到扣减成功Version+1或者商品售完!
如果系统前端不做限流消峰等处理,随意放任大量的并发更新请求直接在数据库中扣减同一热卖商品的库存数据,这将会导致线程之间相互竞争锁,由于数据库中针对同一行数据的更新操作是串行执行的,那么某一个线程在未释放锁之前,其余的线程将会全部阻塞在队列中等待拿锁,并发越高时,等待的线程也就会越多,这会影响数据库的TPS(吞吐量),最终导致系统奔溃。