2019独角兽企业重金招聘Python工程师标准>>>
1.将总库存load进reids系统(假如商品总库存为9995件)
server1,、server2、server3三台服务器负载均衡,每台机器都持有一个临时库存(默认为0),当各个server接受客户端请求进入减库存逻辑时首先减自身的临时库存,临时库存中如果剩余0件则一次性从redis中捞出100件库存(执行jedis.decrBy(store,100)),再减自身临时库存。。。。
注意:redis.decrBy(store,100)如果发现返回的是负数(result),则此时从redis取到的库存应该为(100+result)件,如果小于0的话则代表库存已卖完,可以内置boolean变量,告诉程序以后都不要去redis取库存了,因为早就卖完了...
优点:不会出现超卖情况,很大程度减少redis并发减库存操作,增加高并发性能。。。
缺点:i:如果某台server的临时库存还剩55件,此时该server宕机,测最终会出现少卖了55件;ii:无法获知具体剩余库存量
2.如果总库存存储在数据库中(假如商品总库存为9995件)
这里输入引用文本设计方案可以和第一种思路差不多,减数据库库存增加临时库存方案如下:
update store set totalCount = totalCount -100 where totalCount >= 100 and product_id = 1001
看该sql的影响行数,如果等于1,代表此次减库存操作成功,该语句因为totalCount依赖原值,所以数据库内部会使用行锁来保证并发安全性
这里输入引用文本最后一次减数据库库存的时候因为不满足100件(95件),此时
①update store set totalCount = totalCount -100 where totalCount >= 100 and product_id = 1001
影响行数为0,执行下面2个语句即可
②select totalCount from store where product_id = 1001
结果为95
③update store set totalCount = totalCount -95 where totalCount >= 95 and product_id = 1001
看它的影响行数, 如果为1则代表当前线程减库存成功,否则则代表被其他线程捷足先登了...
语句②和③在线程并发的时候只会有一个成功的,其他线程影响行数都是等于0的,不会出现超卖的...