0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

加锁失效,非锁之过,加之错也

京东云 来源:jf_75140285 作者:jf_75140285 2024-11-05 17:52 次阅读

引言

多个进程或线程同时(或着说在同一段时间内)访问同一资源会产生并发问题。



银行两操作员同时操作同一账户就是典型的例子。比如A、B操作员同时读取一余额为1000元的账户,A操作员为该账户增加100元,B操作员同时为该账户减去 50元,A先提交,B后提交。 最后实际账户余额为1000-50=950元,但本该为1000+100-50=1050。这就是典型的并发问题



从事零售供应链库存业务,对库存数量操作增减十分频繁,同样存在类似上述银行取款遇到的问题,库存数量操作有误势必给前台销售产生损失影响,因此需要关注对库存数量并发操作下的一致性。



下面通过一个真实的案例分享在并发情况下如何保证库存数量的准确性。

问题是什么-加锁失效

看看下面这段流程和代码,思考会有并发问题吗?

wKgaomcoYW-Ae9-CAAFgOMxxRWA504.png



1.加锁前,获取箱子明细数据,此处在锁之外,存在并发脏读问题

wKgZomcoYXCADd8pAAHpaEKHmfo247.png



2.加锁后,并进行箱子上架分批次回传业务处理

wKgaomcoYXKAWp4kAAMnCp_ccqE913.png



3.加锁后,更新箱子明细上架数量逻辑:已上架数量 = 加锁前的明细数据(脏读) + 报文回传的明细数据 直接进行行更新

wKgZomcoYXSAKeLHAAc6EXS9O2o758.png

原因是什么-加锁的位置不正确

wKgaomcoYXWATQwzAAM5pLTPczs062.png

核心的问题原因

1.业务分布式锁失效:使用分布式锁加锁了,但是仍然使用加锁前查询的数据,导致出现脏读

2.Mysql锁失效:数据库更新时,未上任何锁,导致脏读的数据直接覆盖更新当前行



有同学这时问了,为啥防重码也没有生效呢?

防重码主要是用作幂等逻辑的,同一个请求多次处理,结果仍然是相同的。

但是这是两次不同的请求,防重码是不同的,因此不能只依赖防重码保证一致性。



解决方案有哪些

1、代码层面:使用锁(如互斥锁、读写锁、分布式锁等)来控制资源的访问,数据获取的全部操作都需要再获取锁后才进行。

将获取箱子明细的代码移动到加锁之后,只有获取到分布式锁,才能执行分批次上架查询和更新(串行化)

wKgZomcoYXaARau2AALOgDkTuUY983.png

对应改造后的代码:

wKgaomcoYXiAY4NNAAWUowUe7HI787.png



2、数据库层面:实现事务管理,确保数据的一致性;合理设置事务隔离级别,以防止脏读、或者采用乐观锁或悲观锁来处理并发更新,合理设计查询效率,减少锁竞争。

数据库的并发上锁处理和业务代码的上锁是互补的关系

因为无法保证后续业务的调整或其他业务代码的调用能始终保持获取数据的一致性,数据库的并发上锁处理更多是一种兜底保证机制。



乐观锁更新

wKgZomcoYXqAR3Y4AAJBf6DRpQk551.png



悲观锁更新

wKgaomcoYXuAOJ7IAAHiDtjHNY4446.png



扩展方案

1.应用程序设计: 在应用程序设计阶段,尽量避免长时间持有数据库连接或事务,减少并发操作的可能性,利用AI代码评审或者人工提前找出可能出现并发问题的地方;合理设置锁的粒度,避免锁失效。



1. 网络负载层面:采用限流控制访问频率;采用分布式数据库,进行数据分片,降低单节点并发压力;使用负载均衡,将网络请求分发到不同的服务器,提高系统处理并发的能力,防止系统过载。



1.请求层面:前端点击防重、系统幂等防重、尽可能降低同一请求的多次重试访问引起的一致性问题。



通过以上措施,可以在不同层面有效地防止并发问题,保证系统的数据的一致性

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 分布式
    +关注

    关注

    1

    文章

    854

    浏览量

    74434
  • 代码
    +关注

    关注

    30

    文章

    4719

    浏览量

    68207
收藏 人收藏

    评论

    相关推荐

    阻塞赋值容易语法点讨论

    本帖最后由 eehome 于 2013-1-5 10:05 编辑 阻塞赋值容易语法点讨论请教下大家!我发现光盘里的例程有一段是这样子的:always @(dac_sta
    发表于 12-22 09:53

    Linux高级编程---互斥

    当前互斥被解锁。pthread_mutex_trylock()函数是一个阻塞型的上锁函数,如果互斥没被锁住,pthread_mutex_trylock()函数将把互斥
    发表于 01-13 10:07

    转第16章 FreeRTOS调度,任务和中断

    的任务函数,但是使用FreeRTOS现有的功能有两种实现方法:(1)通过给调度器加锁实现利用FreeRTOS的调度功能给调度器加锁的话,将关闭任务切换功能,从而高优先级任务也就无法
    发表于 09-01 07:45

    STM32F427的FMC地址数据总线复用控制SRAM必须要加锁存器吗

    用STM32F427的FMC控制SRAM,由于端口不够用,想用FMC的数据地址总线复用功能,请问,是不是要加锁存器存地址,求电路
    发表于 09-18 11:35

    设计电子密码时,怎么实现控制密码输几次就不能再输入的功能

    设计电子密码时,怎么实现控制密码输几次就不能再输入的功能
    发表于 06-19 20:36

    带自功能的密码制作方法分享

    开锁。先按AN7不能开锁已如上述。本密码的按键顺序只能是AN2、AN5、AN7。当按下任何一个密码键时,SCR1导通,使VT2饱和导通,各按键失效,电路锁定为关断状态。这时必须断
    发表于 05-20 06:43

    Altium Designer规则设计技巧之过孔和焊盘

    本文主要介绍了Altium Designer规则设计技巧之过孔和焊盘.
    发表于 06-22 08:00 34次下载
    Altium Designer规则设计技巧<b class='flag-5'>之过</b>孔和焊盘

    详解/互锁/自的区别

    为了满足不同的应用需要,解码接收电路的输出模式通常分为,互锁,自,混合输出。几种模式通俗的说,锁相当于轻触开关,互锁相当于风扇的档位开关,自锁相当于电灯开关。
    发表于 10-07 15:26 7618次阅读

    指纹密码失效原因及对应的解决方案

    密码指纹失效怎么办?指纹密码失效是什么原因造成的?在部分用户使用指纹的时候,会有小概率发生指纹失效
    发表于 06-12 14:30 10.3w次阅读

    select......for update会表还是行?

    验证 结合一下实例验证 结果   select查询语句是不会加锁的,但是select .......for update除了有查询的作用外,还会加锁呢,而且它是悲观。 那么它加的是行
    的头像 发表于 10-10 15:54 1468次阅读

    Linux互斥的作用 互斥是什么

    1、互斥 互斥(mutex),在访问共享资源之前对互斥进行上锁,在访问完成后释放互斥(解锁);对互斥进行上锁之后,任何其它试图再次
    的头像 发表于 07-21 11:13 881次阅读

    读写的实现原理规则

    读写 互斥或自旋要么是加锁状态、要么是不加锁状态,而且一次只有一个线程可以对其加锁。 读写
    的头像 发表于 07-21 11:21 833次阅读
    读写<b class='flag-5'>锁</b>的实现原理规则

    数据库如何实现分布式

    主要是用来避免死锁,防止不必要的线程等待和资源浪费 可重入性 一个线程在持有的情况下,可以再次请求加锁 高性能,高可用 加锁释放的操作尽量使用更少的资源,提高性能。同时也要保证高可
    的头像 发表于 10-08 16:12 4528次阅读

    什么是分布式 Redis的五种分布式方案

    本地加锁的方式在分布式的场景下不适用,所以本文我们来探讨下如何引入分布式解决本地的问题。本篇所有代码和业务基于我的开源项目 PassJava。
    发表于 10-23 11:35 1034次阅读
    什么是分布式<b class='flag-5'>锁</b> Redis的五种分布式<b class='flag-5'>锁</b>方案

    C语言加锁没有锁住是什么原因?

    C语言加锁没有锁住是什么原因? C语言中的机制主要是通过线程库提供的函数来实现的,主要用于多线程编程中的资源同步与互斥。加锁的目的是确保同一时刻只有一个线程可以访问某个共享资源,以防止数据竞争
    的头像 发表于 11-22 17:41 587次阅读