扣库存

1. 事务+锁 只适合单体应用

(1)MySQL默认事务隔离级别为可重复读,即1个事务多次读取同1条记录,返回的结果相同,但这只限于读操作。如果其它事务修改了记录,1个事务多次读取同1条记录,返回结果不同

(2)扣库存是1个复合操作,可以分解为,读取库存的值,对库存值进行减操作,将新增写回数据库

(3)在高并发下,如果不加锁,复合操作不能保证原子性。n个线程执行扣库存操作,线程安全情况下,库存值被-n;但如果不加锁,库存值被减的次数肯定<n

(4)例如线程A,查询DB,得到库存值100,将100-1,再写回DB。在未写入DB时,线程B查询DB,得到的库存值也是100,将100-1,再写回DB。此时库存值应该是98,但实际却是99,丢失1次操作

缺点: 使用JVM锁保证线程安全,只适合单体应用,在分布式下,无法保证

下单即减库存,不会出现超卖,但会出现少卖。对于下单的未付款的订单,超时将库存加回来(定时任务)

2. 事务+分布式锁 适合分布式应用,但是性能差,不使用

分布式系统下,每个应用多实例部署,相互独立,部署在单独的Web容器上,无法使用JVM锁保证线程安全。但是可以使用分布式锁,每个应用在扣库存时,去请求分布式锁,请求到的应用对库存进行减操作

缺点: 每次减库存,都需要请求分布式锁,走1次网络,性能差

3. 分库分表,将库存分为多份,由多个实例的数据库持有。库存总量单独存放在分布式系统的节点上。让多个实例轮询处理请求(使用Ribbon的负载均衡机制;传统方式可以通过对userID进行取余或Hash,将请求路由到对应的数据库和表),也就是轮询的扣库存,当库存扣完时,向库存总量申请,如果还有库存,可以继续扣库存,否则库存为0,不能再卖

(1)减少请求分布式锁的次数
实例扣完库存后,向库存总量申请,使用分布式锁做同步。与每1次扣库存都申请分布式锁相比,减少了请求锁的次数,不用每次都走网络。例如,10000个库存,分成10个实例,每个实例持有500个,扣完时向库存总量申请,最多会请求20次锁;但每次都请求分布式锁,需要请求10000次

(2)根据业务并发数,合理设置超时时间
Feign使用Ribbon和Hystrix,Ribbon和Hystrix都有超时时间。Hystrix默认1s,如果超时会执行fallback;Ribbon的connect超时和read超时默认都是1s

对于1000个线程的并发,经过测试,设置Ribbon read超时为3s, connect超时使用默认1s

高版本Feign默认关闭了重试,会和Ribbon重试冲突
(1)设置Ribbon的read超时时间和connect超时时间;设置1台Server的重试次数,设置最大重试的Server数;设置重试策略
默认情况,GET请求 read超时/connect超时,都会重试; 非GET请求,只对connect超时进行重试

(2)启用Feign的Hystrix,超时时间根据Ribbon重试策略设置;不要出现Ribbon还在重试,而Hystrix超时的情况

设置连接数
show variables like 'max_connections';
set GLOBAL max_connections=1000;

service层事务+synchronized,导致线程不安全

锁加在service层事务方法上,多个线程执行时,1个线程获取锁,其它线程等待。当1个线程执行完,退出同步块时,事务还未提交;MySQL默认事务隔离级别,是可重复读,SELECT结果是事务开始时间点的状态,当此时其它线程执行读取操作,读取的值是旧值,导致2个线程对同1个旧值执行操作,丢失1次操作

解决方式: 将synchronized加在Controller方法中

4. 只使用Redis

  1. Lua脚本,库存>0时,扣库存;库存=0时,不再操作

  2. 应用Redis单线程机制

  3. Redis崩溃,要有应对方案
    最简单的,使用AOF,不使用RDB

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,451评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,172评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,782评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,709评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,733评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,578评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,320评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,241评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,686评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,878评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,992评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,715评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,336评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,912评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,040评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,173评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,947评论 2 355

推荐阅读更多精彩内容

  • Java继承关系初始化顺序 父类的静态变量-->父类的静态代码块-->子类的静态变量-->子类的静态代码快-->父...
    第六象限阅读 2,157评论 0 9
  • 关于Mongodb的全面总结 MongoDB的内部构造《MongoDB The Definitive Guide》...
    中v中阅读 31,936评论 2 89
  • 无论是日常工作中,还是面试问题中,并发扣库存都是一个很常见的场景,正好业务里有这样的场景,可以对这类问题做一下总结...
    测试你个头阅读 5,080评论 1 35
  • ORA-00001: 违反唯一约束条件 (.) 错误说明:当在唯一索引所对应的列上键入重复值时,会触发此异常。 O...
    我想起个好名字阅读 5,317评论 0 9
  • 一、松竹梅岁寒三友, 二、智取威虎山, 三、强壮如牛, 四、元宝, 五、白手起家, 以上各打一字
    贯华阅读 394评论 1 2