并发控制:确保数据一致性的策略

2024-06-17 10:28

本文主要是介绍并发控制:确保数据一致性的策略,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

引言

​ 在现代软件开发中,尤其是在涉及高并发场景的应用,如在线购物、金融交易等,保证数据操作的原子性和一致性是至关重要的。本文将深入探讨并发环境下常见的问题,以及如何通过先进的技术手段确保数据的准确性和安全性。

案例分析:库存扣减的并发挑战
背景设定

​ 设想一个在线电商平台,其后端数据库中有一个名为 stock 的库存数据表,其中 stock_num 字段记录了商品的库存数量。

并发扣减库存的问题

​ 在高流量的购物节期间,库存扣减操作变得尤为关键。一个典型的扣减操作可能是执行如下 SQL 语句:

UPDATE stock SET stock_num = stock_num - 1 WHERE product_id = X;

以上操作会产生什么问题?

​ **不幂等:**当上次语句重复执行的时候会导致多次扣减库存,为什么会重复执行,比如业务侧重试、数据库代理重试等,因此我们可以先查出库存数量,得出新库存等于 new_stock = stock_num - 1, 最终语句如下:

update stock set stock_num = new_stock

​ **超卖:**并发场景解决了不幂等问题之后依然存在超卖问题,假如库存剩余1,两个并发请求同时查询库存为1,此时 new_stock_num = 1-1 ,两个请求同时执行 update stock set stock_num = new_stock_num,只有一个库存却卖出两件

怎么解决超卖问题

CAS(Compare-And-Swap) 机制的应用:我们在语句后面加上库存数量判断即可 ,然后根据 affetc row 0或1判断执行有没有成功,语句如下:

 update stock set stock_num  = new_stock_num where stock_num = old_stock_num

解决以上问题就万事大吉了吗,其实以上写法还有可能存在经典 ABA 问题

深入探讨:ABA 问题的识别与解决

​ 尽管 CAS 机制可以解决不幂等性和超卖问题,但它本身也有局限性,即所谓的 ABA 问题。ABA 问题描述了在并发编程中,一个值从 A 变为 B,再变回 A,而 CAS 操作却可能错误地认为值未发生变化。

举例解释:

  1. 张三去银行取钱,余额有 200 元,张三取 100 元,但因为程序的问题,启动了两个线程,线程一和线程二进行比对扣款,线程一获取原本有 200 元,扣除 100 元,余额等于 100 元 - 此时余额是100

  2. 李四给张三转账 100 元,于是启动了线程三抢先在线程二之前执行了转账操作,把 100 元又变成了 200 元 - 经过转账又变成了200

  3. 此时线程二对比自己事先拿到的 200 元和此时经过改动的 200 元值一样,就进行了减法操作,把余额又变成了 100 元 - 线程2是步骤一异常启动的线程,我们期望线程2不应该扣款但由于执行语句的判断条件是 old_money=200, 由于 ABA 问题导致条件判断成功,导致多扣了100

解决方案:引入版本号

​ ABA 问题的核心原因是因为被更新的变量会有加减操作,所以导致值会在新老数值之间变动,如果值只加不减,那么判断条件是不是就可以成立了,所以我们可以引入一个版本号字段 version,此时更新语句变成:

update stock set stock_num  = new_stock_num, version = new_version where stock_num = old_stock_num and version = old_version
Reference
  1. 深入理解 CAS 和 ABA 问题

这篇关于并发控制:确保数据一致性的策略的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1069184

相关文章

【服务器运维】MySQL数据存储至数据盘

查看磁盘及分区 [root@MySQL tmp]# fdisk -lDisk /dev/sda: 21.5 GB, 21474836480 bytes255 heads, 63 sectors/track, 2610 cylindersUnits = cylinders of 16065 * 512 = 8225280 bytesSector size (logical/physical)

SQL Server中,查询数据库中有多少个表,以及数据库其余类型数据统计查询

sqlserver查询数据库中有多少个表 sql server 数表:select count(1) from sysobjects where xtype='U'数视图:select count(1) from sysobjects where xtype='V'数存储过程select count(1) from sysobjects where xtype='P' SE

Java研学-RBAC权限控制(八)

九 登录登出 1 登录作用   判断员工是否有权限访问,首先得知道现在操作的人是谁,所以必须先实现登录功能 2 登录流程   ① 提供登录页面,可输入用户名与密码信息,并添加执行登录的按钮。(登录页面不能被拦截)   ② 给按钮绑定点击事件(异步操作,POST请求)   ③ 事件中发送登录请求,使用 AJAX 方式提交。(使用 AJAX 原因:用户体验更好,既可保留用户刚输入的用户名和密码

数据时代的数字企业

1.写在前面 讨论数据治理在数字企业中的影响和必要性,并介绍数据治理的核心内容和实践方法。作者强调了数据质量、数据安全、数据隐私和数据合规等方面是数据治理的核心内容,并介绍了具体的实践措施和案例分析。企业需要重视这些方面以实现数字化转型和业务增长。 数字化转型行业小伙伴可以加入我的星球,初衷成为各位数字化转型参考库,星球内容每周更新 个人工作经验资料全部放在这里,包含数据治理、数据要

如何在Java中处理JSON数据?

如何在Java中处理JSON数据? 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们将探讨在Java中如何处理JSON数据。JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,在现代应用程序中被广泛使用。Java通过多种库和API提供了处理JSON的能力,我们将深入了解其用法和最佳

两个基因相关性CPTAC蛋白组数据

目录 蛋白数据下载 ①蛋白数据下载 1,TCGA-选择泛癌数据  2,TCGA-TCPA 3,CPTAC(非TCGA) ②蛋白相关性分析 1,数据整理 2,蛋白相关性分析 PCAS在线分析 蛋白数据下载 CPTAC蛋白组学数据库介绍及数据下载分析 – 王进的个人网站 (jingege.wang) ①蛋白数据下载 可以下载泛癌蛋白数据:UCSC Xena (xena

服务器雪崩的应对策略之----SQL优化

SQL语句的优化是数据库性能优化的重要方面,特别是在处理大规模数据或高频访问时。作为一个C++程序员,理解SQL优化不仅有助于编写高效的数据库操作代码,还能增强对系统性能瓶颈的整体把握。以下是详细的SQL语句优化技巧和策略: SQL优化 1. 选择合适的数据类型2. 使用索引3. 优化查询4. 范式化和反范式化5. 查询重写6. 使用缓存7. 优化数据库设计8. 分析和监控9. 调整配置1、

设置Nginx缓存策略

详细信息 Nginx服务器的缓存策略设置方法有两种:add_header或者expires。 1. add_header 1)语法:add_header name value。 2)默认值:none。 3)使用范围:http、server、location。 配置示例如下: add_header cache-control "max-age=86400";#设置缓存时间为1天。add

中国341城市生态系统服务价值数据集(2000-2020年)

生态系统服务反映了人类直接或者间接从自然生态系统中获得的各种惠益,对支撑和维持人类生存和福祉起着重要基础作用。目前针对全国城市尺度的生态系统服务价值的长期评估还相对较少。我们在Xie等(2017)的静态生态系统服务当量因子表基础上,选取净初级生产力,降水量,生物迁移阻力,土壤侵蚀度和道路密度五个变量,对生态系统供给服务、调节服务、支持服务和文化服务共4大类和11小类的当量因子进行了时空调整,计算了

ROS2从入门到精通4-4:局部控制插件开发案例(以PID算法为例)

目录 0 专栏介绍1 控制插件编写模板1.1 构造控制插件类1.2 注册并导出插件1.3 编译与使用插件 2 基于PID的路径跟踪原理3 控制插件开发案例(PID算法)常见问题 0 专栏介绍 本专栏旨在通过对ROS2的系统学习,掌握ROS2底层基本分布式原理,并具有机器人建模和应用ROS2进行实际项目的开发和调试的工程能力。 🚀详情:《ROS2从入门到精通》 1 控制插