当前位置: 首页 > news >正文

加锁失效,非锁之过,加之错也|京东零售供应链库存研发实践

本文导读

从事京东零售供应链库存业务,库存数量操作增减十分频繁,并且项目开发中会常常遇到各种并发情况,一旦库存数量操作有误,势必给前台销售产生损失影响,因此需要关注对库存数量并发操作下的一致性问题。 

大部分情况下,加锁可以很好地解决并发问题,但是只要加上锁后就一定不会有并发问题吗?哪些情况下引起锁失效呢?本文会以一个真实的线上案例来剖析业务处理加锁过程易使用不当的点以及对应的解决方案。

 

引言

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

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

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

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

 

问题是什么-加锁失效

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

图片

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

图片

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

图片

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

图片

 

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

图片

核心的问题原因

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

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

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

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

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

解决方案有哪些

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

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

图片

对应改造后的代码:

图片

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

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

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

乐观锁更新

图片

悲观锁更新

图片

扩展方案

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

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

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

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

相关文章:

加锁失效,非锁之过,加之错也|京东零售供应链库存研发实践

本文导读 从事京东零售供应链库存业务,库存数量操作增减十分频繁,并且项目开发中会常常遇到各种并发情况,一旦库存数量操作有误,势必给前台销售产生损失影响,因此需要关注对库存数量并发操作下的一致性问题。 大部分…...

vue3 传值的几种方式

一.父组件传子组件 父组件 //父组件 <Decisionobject :Decisionselected"Decisionselected"></Decisionobject> <script lang"ts" setup> let Decisionselected ref(false); </script>子组件 <script lang"ts" s…...

AUTOSAR CP NVRAM Manager规范导读

一、NVRAM Manager功能概述 NVRAM Manager是AUTOSAR(AUTomotive Open System ARchitecture)框架中的一个模块,负责管理非易失性随机访问存储器(NVRAM)。它提供了一组服务和API,用于在汽车环境中存储、维护和恢复NV数据。以下是NVRAM Manager的一些关键功能: 数据存储和…...

2024阿里云CTF Web writeup

《Java代码审计》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484219&idx1&sn73564e316a4c9794019f15dd6b3ba9f6&chksmc0e47a67f793f371e9f6a4fbc06e7929cb1480b7320fae34c32563307df3a28aca49d1a4addd&scene21#wechat_redirect 前言 又是周末…...

软件著作权申请教程(超详细)(2024新版)软著申请

目录 一、注册账号与实名登记 二、材料准备 三、申请步骤 1.办理身份 2.软件申请信息 3.软件开发信息 4.软件功能与特点 5.填报完成 一、注册账号与实名登记 首先我们需要在官网里面注册一个账号&#xff0c;并且完成实名认证&#xff0c;一般是注册【个人】的身份。中…...

三维测量与建模笔记 - 3.2 直接线性变换法标定DLT

DLT - Direct Linear Transform 上图中&#xff0c;透视成像对应的公式是共线方程&#xff0c;可以参考以下链接&#xff1a; https://zhuanlan.zhihu.com/p/101549821https://zhuanlan.zhihu.com/p/101549821 对于标定来说&#xff0c;需要找到。已知量是。 (u,v)是…...

Whisper AI视频(音频)转文本

在信息化时代&#xff0c;如何高效处理丰富的音频和视频内容成为了一个重要课题。将这些内容转化为文本不仅能提高信息的可获取性&#xff0c;还能促进更广泛的传播。Whisper Desktop作为一款先进的语音识别工具&#xff0c;能够帮助用户轻松实现音频和视频的转文本功能。 什么…...

全网最详细RabbitMQ教学包括如何安装环境【RabbitMQ】RabbitMQ + Spring Boot集成零基础入门(基础篇)

目录 一、初始Rabbitmq1、什么是Rabbitmq&#xff0c;它的概述是什么&#xff1f;2、RabbitMQ的应用场景3、RabbitMQ主要组件4、RabbitMQ 的优点5、与其他消息队列性能比较 二、RabbitMQ环境安装初始化三、SpringAMQPRabbitMQ实战入门&#xff08;基本API&#xff09;1、实战入…...

esp32记录一次错误

报错信息 PS C:\XingNian\GeRen\4Gdownload\wireless-esp8266-dap> idf.py build Executing action: all (aliases: build) Running cmake in directory c:\xingnian\geren\4gdownload\wireless-esp8266-dap\build Executing "cmake -G Ninja -DPYTHON_DEPS_CHECKED1 …...

Moonshine - 新型开源ASR(语音识别)模型,体积小,速度快,比OpenAI Whisper快五倍 本地一键整合包下载

Moonshine 是由 Useful Sensors 公司推出的一系列「语音到文本&#xff08;speech-to-text, STT&#xff09;转换模型」&#xff0c;旨在为资源受限设备提供快速而准确的「自动语音识别&#xff08;ASR&#xff09;服务」。Moonshine 的设计特别适合于需要即时响应的应用场景&a…...

java-web-苍穹外卖-day1:软件开发步骤简化版+后端环境搭建

软件开发 感觉书本上和线上课程, 讲的太抽象, 不好理解, 但软件开发不就是为了开发应用程序吗?! 干嘛搞这么抽象,对吧, 下面个人对于软件开发的看法, 主打简单易懂, 当然,我一IT界小菜鸟, 对软件开发的认识也很浅显, 这个思维导图也仅仅是现阶段我的看法, 我以后会尽力…...

一个国产 API 开源项目,在 ProductHunt 杀疯了...

随着AI 大模型技术的兴起&#xff0c;全球产品更新和面市进程速度肉眼可见的加快&#xff0c;Product Hunt 作为全球知名的产品发现平台&#xff0c;每日都会精选出一系列产品能力强劲的新产品&#xff0c;这些产品不仅代表了技术前沿&#xff0c;还反映了市场的发展趋势。 上…...

斗破QT编程入门系列之二:认识Qt:编写一个HelloWorld程序(四星斗师)

斗破Qt目录&#xff1a; 斗破Qt编程入门系列之前言&#xff1a;认识Qt&#xff1a;Qt的获取与安装&#xff08;四星斗师&#xff09; 斗破QT编程入门系列之一&#xff1a;认识Qt&#xff1a;初步使用&#xff08;四星斗师&#xff09; 斗破QT编程入门系列之二&#xff1a;认识…...

木马病毒相关知识

1、 木马的定义 相当于一个远控程序&#xff08;一个控制端[hack]、一个被控端[受害端]&#xff09; 在计算机系统中&#xff0c;“特洛伊木马”指系统中被植入的、人为设计的程序&#xff0c;目的包括通过网终远程控制其他用户的计算机系统&#xff0c;窃取信息资料&#xff0…...

用 Python 写了一个天天酷跑(附源码)

Hello&#xff0c;大家好&#xff0c;给大家说一下&#xff0c;我要开始装逼了 这期写个天天酷跑玩一下叭&#xff01; 制作一个完整的“天天酷跑”游戏涉及很多方面&#xff0c;包括图形渲染、物理引擎、用户输入处理、游戏逻辑等。由于Python是一种高级编程语言&#xff0c;…...

【网络-交换机】生成树协议、环路检测

路由优先级 路由优先级决定了在多种可达的路由类型中&#xff0c;哪种路由将被用来转发数据包。路由优先级值越低&#xff0c;对应路由的优先级越高&#xff0c;优先级值255表示对应的路由不可达。一般情况下&#xff0c;静态路由的优先级为1&#xff0c;OSPF路由优先级为110&a…...

C++ 中的 JSON 序列化和反序列化:结构体与枚举类型的处理

在 C 编程中&#xff0c;处理 JSON 数据是一项常见任务&#xff0c;特别是在需要与其他系统或前端进行数据交换时。nlohmann::json 库是一个功能强大且易于使用的 JSON 库&#xff0c;它允许我们轻松地在 C 中进行 JSON 数据的序列化和反序列化。本文将详细介绍如何使用 nlohma…...

MySQL 批量删除海量数据的几种方法

目录 一、问题分析 二、批量删除海量数据的几种方法 方法 1&#xff1a;使用 LIMIT 分批删除 方法 2&#xff1a;通过主键范围分批删除 方法 3&#xff1a;通过自定义批量删除存储过程 方法 4&#xff1a;创建临时表替换旧表 三、性能优化建议 总结 在数据库的日常维护…...

【docker入门】docker的安装

目录 Centos 7 添加docker 官方仓库到yum源 将 Docker 的官方镜像源替换为国内可以的 Docker 镜像源 安装docker 配置docker加速源 Ubuntu 创建 gpg key 目录 下载 gpg key 添加国内可用镜像源到 系统的 APT 仓库中 安装docker 配置加速源 Centos 7 添加docker 官方仓…...

单例模式五种写法

饿汉式&#xff08;线程安全&#xff09; public class Singleton {// 直接创建实例&#xff0c;在类加载时就完成实例化private static final Singleton instance new Singleton();// 私有构造函数private Singleton() {}// 提供公共的静态方法获取实例public static Single…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

基于Java+MySQL实现(GUI)客户管理系统

客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...

MySQL:分区的基本使用

目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区&#xff08;Partitioning&#xff09;是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分&#xff08;分区&#xff09;可以独立存储、管理和优化&#xff0c;…...

sshd代码修改banner

sshd服务连接之后会收到字符串&#xff1a; SSH-2.0-OpenSSH_9.5 容易被hacker识别此服务为sshd服务。 是否可以通过修改此banner达到让人无法识别此服务的目的呢&#xff1f; 不能。因为这是写的SSH的协议中的。 也就是协议规定了banner必须这么写。 SSH- 开头&#xff0c…...

【Axure高保真原型】图片列表添加和删除图片

今天和大家分享图片列表添加和删除图片的原型模板&#xff0c;效果包括&#xff1a; 点击图片列表的加号可以显示图片选择器&#xff0c;选择里面的图片&#xff1b; 选择图片后点击添加按钮&#xff0c;可以将该图片添加到图片列表&#xff1b; 鼠标移入图片列表的图片&…...

LangChain + LangSmith + DeepSeek 入门实战:构建代码生成助手

本文基于 Jupyter Notebook 实践代码&#xff0c;结合 LangChain、LangSmith 和 DeepSeek 大模型&#xff0c;手把手演示如何构建一个代码生成助手&#xff0c;并实现全流程追踪与优化。 一、环境准备与配置 1. 安装依赖 pip install langchain langchain_openai2. 设置环境变…...