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

数据库锁的设计

近期开发与钱相关的项目,在高并发场景下对数据的准确行有很高的要求,用到了for update,故总结一波以便日后留恋。

for update的使用场景

如果遇到存在高并发并且对于数据的准确性很有要求的场景,例如支付、对账等,是需要了解和使用for update的。

比如涉及到金钱、库存等。一般这些操作都是很长一串并且是开启事务的。如果库存刚开始读的时候是1,而立马另一个进程进行了update将库存更新为0了,而事务还没有结束,会将错的数据一直执行下去,就会有问题。所以需要for upate 进行数据加锁防止高并发时候数据出错。
for update必须在事务块(BEGIN/COMMIT)中才能生效。在进行事务操作时,通过“for update”语句,MySQL与ORCALE 会对查询结果集中每行数据都添加排他锁,其他线程对该记录的更新与删除操作都会阻塞。排他锁包含行锁、表锁。

一、数据一致性

假设有A、B两个用户同时各购买一件 id=1 的商品,用户A获取到的库存量为 1000,用户B获取到的库存量也为 1000,用户A完成购买后修改该商品的库存量为 999,用户B完成购买后修改该商品的库存量为 999,此时库存量数据产生了不一致。

有两种解决方案:

悲观锁方案

:每次获取商品时,对该商品加排他锁。也就是在用户A获取获取 id=1 的商品信息时对该行记录加锁,期间其他用户阻塞等待访问该记录。悲观锁适合写入频繁的场景。

begin;

select * from goods where id = 1 for update;

update goods set stock = stock - 1 where id = 1;

commit;

乐观锁方案

:每次获取商品时,不对该商品加锁。在更新数据的时候需要比较程序中的库存量与数据库中的库存量是否相等,如果相等则进行更新,反之程序重新获取库存量,再次进行比较,直到两个库存量的数值相等才进行数据更新。乐观锁适合读取频繁的场景。

#不加锁获取 id=1 的商品对象

select * from goods where id = 1

begin;

#更新 stock 值,这里需要注意 where 条件 “stock = cur_stock”,只有程序中获取到的库存量与数据库中的库存量相等才执行更新

update goods set stock = stock - 1 where id = 1 and stock = cur_stock;

commit;

如果我们需要设计一个商城系统,该选择以上的哪种方案呢?

查询商品的频率比下单支付的频次高,基于以上我可能会优先考虑第二种方案(当然还有其他的方案,这里只考虑以上两种方案)。

InnoDB默认是行级别的锁,当有明确指定的主键时候,是行级锁。否则是表级别。

#for update的注意点
for update 必须开启事务,在begin与commit之间才生效。

总结

一般在支付、商品交易的库存变更等业务场景采用悲观锁方案;
在广告、电商浏览页面、投票等场景采用乐观锁方案


http://www.kler.cn/a/158544.html

相关文章:

  • 第二十五章 TCP 客户端 服务器通信 - TCP 设备的 READ 命令
  • java8 快捷方式
  • linux004.在ubuntu中smb.conf配置文件中配置内容详解
  • Spring Security 核心组件
  • 智慧安防丨以科技之力,筑起防范人贩的铜墙铁壁
  • Ascend C算子性能优化实用技巧05——API使用优化
  • 内部文件上传以及渲染-接口API
  • 技巧-PyTorch中num_works的作用和实验测试
  • 深度学习|keras编程基础
  • 更换cmd下默认选择Python解释器
  • Rust的From与Into Trait
  • 对标Gen-2!Meta发布新模型,进军文生视频赛道
  • 使用晶振遇到的两个问题
  • .NET微信网页开发相关文章教程
  • 电脑上mp4视频文件无缩略图怎么办
  • 在python的Scikit-learn库中,可以使用train_test_split函数来划分训练集和测试集。
  • Servlet基础知识
  • 在机器学习或者深度学习中是否可以直接分为训练集和测试集而不需要验证集?我的答案如下:
  • 解决cad找不到msvcr100.dll的有效方法,完美修复dll问题
  • UVC debug 工具
  • 计数问题(数位DP)
  • 如何将 Python 2 代码移植到 Python 3
  • Web开发-问题-前后端交互数据不一致
  • 网工内推 | 上市公司初级网工,HCIP认证优先,14薪,享企业年金
  • 记录 | CUDA编程中 __host__ 标识符可以省略的情况
  • Excel如何比较两列数据的不同