1、在设计公司的库存架构的时候,出现了问题,当处理无座商品的时候,发现,回滚逻辑有问题,具体的逻辑为:

比如如果库存设置为1 ,则 

(1) 用户1 下单成功,库存-1

(2)用户2下单因为库存 是0所以 下单失败,开始回滚,回滚的时候+1,导致目前的库存为 1(实际上这个库存已经被用户1买走了)
(3)用户3 下单成功 ,库存-1

最后:导致库存1 卖了2次,

原因分析:

回滚逻辑没有显示订单号,应该严格按照订单号回滚,否则会把别人的库存回滚掉;

 

大麦的逻辑设置:

库存回滚架构设计原则_死锁

 

首先第一步:

假设库存总量为total_count,本次用户下单的数量为10;

数据库有3列,总 total_count,已售: sale_count,剩余 marging_count;

这些都放在一个事务中

 

 

try{

1、查询订单库存,如果库存不足直接返回 查询的条件唯一(比如按照订单号)

2、将库存锁定比如 1是未锁定,2是锁定 则 设置当前的行为锁定状态;

update recrod set status=2 where status=1 and 条件;

3、如果需要修改的库存有多条,对需要修改的库存进行排序(防止死锁)

4、逐行设置库存:

update sale_count+10 ,margin_count-10  where 条件+status=2 and sale_count-10>=0; 

} catch(Exception e){

}

 

之所以如此设置:

1、全部放在一个事务中,方便异常回滚,

2、使用一个status锁定状态,因为mysql是行锁,保证事务并发处理的时候只有个线程可以往后走,后面的线程会等待,处理一条数据,

3、指定一个唯一条件,比如按照订单号回滚,如果订单号不满足直接退出,防止回滚别人的库存

4、设置库存的时候,需要先进行排序,让线程顺序执行,防止死锁,举个栗子:

如果不排序:A,B两个线程 ,回滚库存 ,如果第一个A线程扣减了X1行,下一步执行Y1行,

但另一个线程B,扣减了Y1,下一步需要扣减X1行,这时候,

A线程占着X1行,需要等待B线程释放Y1行,

而同时B线程占着Y1行,等待着A线程释放X1行,

库存回滚架构设计原则_数据库_02

产生了死锁

所以必须要排序;

5、扣减的时候执行 条件添加:sale_count-10>=0; 保证即使某个地方有问题,也不会扣减为负数; 

 

 

 

 

 

  

 

问题:1、sale_count-10>=0; 不是小于=0;

是的;

2、排序如何排序,根据什么条件排序 根据票品的ID进行排序,保证顺序;

3、我们的设置状态是锁定状态?那也就是每个库存都要设置一个是否锁定的状态? 还是专门设计一张表,锁定状态,卖座的优惠券发券如何设计

可以加一张新表把状态放进来;