0

0

mysql并发下如何控制请求顺序_mysql队列化思路

P粉602998670

P粉602998670

发布时间:2025-12-31 09:32:02

|

955人浏览过

|

来源于php中文网

原创

高并发下防超卖需用SELECT...FOR UPDATE行锁,必须命中索引;无强序需求可用唯一约束+ON DUPLICATE KEY UPDATE;严格FIFO应交由Redis队列处理,避免依赖AUTO_INCREMENT或时间戳排序。

mysql并发下如何控制请求顺序_mysql队列化思路

SELECT ... FOR UPDATE 实现行级排队

在高并发更新同一行数据时(比如库存扣减),直接 UPDATE 可能导致超卖。必须让请求串行化处理该行。核心是先查再锁,且查询必须命中索引——否则会升级为表锁或锁住不相关记录。

  • SELECT stock FROM goods WHERE id = 123 FOR UPDATE 必须基于主键或唯一索引,否则 MySQL 可能加间隙锁(Gap Lock)锁住更大范围
  • 事务中不能只执行这句就提交,必须紧接着做 UPDATECOMMIT,否则锁会持续到事务结束,拖慢整体吞吐
  • 应用层需设置合理超时,例如 JDBC 的 setQueryTimeout(),避免某请求卡死导致后续全部阻塞

INSERT ... SELECT ... ON DUPLICATE KEY UPDATE无锁队列写入

当“排队”目标不是强一致性顺序,而是防止重复处理(如防重下单),可用唯一约束 + 插入冲突回退替代显式加锁。它比 FOR UPDATE 更轻量,但不保证全局执行顺序。

  • 建表时给业务唯一键(如 order_no)加 UNIQUE 索引
  • INSERT INTO queue_log (order_no, status, created_at) VALUES ('NO123', 'pending', NOW()) ON DUPLICATE KEY UPDATE status = VALUES(status)
  • 插入成功说明是第一个请求;冲突则说明已有同订单在处理中,当前请求可直接跳过或轮询状态

用 Redis List + Lua 做外部协调队列

MySQL 本身不提供消息队列能力,纯靠数据库实现严格 FIFO 容易成为瓶颈。更常见的做法是把“排队逻辑”下沉到 Redis,MySQL 只负责最终状态落地。

SlidesAI
SlidesAI

使用SlidesAI的AI在几秒钟内创建演示文稿幻灯片

下载
  • LPUSH queue:order 入队,BRPOP queue:order 0 阻塞取任务,天然保序
  • 关键操作必须原子:用 Lua 脚本封装「取任务 + 标记处理中 + 设置超时」,避免多个 worker 同时取到同一任务
  • MySQL 更新只在 worker 拿到任务后执行,此时已脱离并发争抢,只需保证单次更新正确性即可

为什么不能依赖 AUTO_INCREMENT 或时间戳排序请求

很多人误以为插入时的自增 ID 或 NOW() 时间就能代表请求到达顺序,实际在并发下完全不可靠。

  • AUTO_INCREMENT 在批量插入、InnoDB 的 innodb_autoinc_lock_mode=2(默认)下可能跳号、乱序分配
  • NOW() 精度只有秒级(5.6 及以前)或微秒级(5.7+),但同一微秒内仍可能有多个请求,且写入落盘顺序≠执行顺序
  • 主从复制、连接池复用、事务延迟提交都会进一步打乱“看起来的时间顺序”
-- 错误示例:以为按 id 升序就是请求顺序
SELECT * FROM order_log ORDER BY id ASC; -- 实际可能漏掉未提交事务的记录,或被 gap lock 影响可见性

真正需要顺序控制的地方,必须显式引入锁、队列或版本号机制,而不是依赖数据库的隐式行为。

相关专题

更多
mysql修改数据表名
mysql修改数据表名

MySQL修改数据表:1、首先查看数据库中所有的表,代码为:‘SHOW TABLES;’;2、修改表名,代码为:‘ALTER TABLE 旧表名 RENAME [TO] 新表名;’。php中文网还提供MySQL的相关下载、相关课程等内容,供大家免费下载使用。

652

2023.06.20

MySQL创建存储过程
MySQL创建存储过程

存储程序可以分为存储过程和函数,MySQL中创建存储过程和函数使用的语句分别为CREATE PROCEDURE和CREATE FUNCTION。使用CALL语句调用存储过程智能用输出变量返回值。函数可以从语句外调用(通过引用函数名),也能返回标量值。存储过程也可以调用其他存储过程。php中文网还提供MySQL创建存储过程的相关下载、相关课程等内容,供大家免费下载使用。

244

2023.06.21

mongodb和mysql的区别
mongodb和mysql的区别

mongodb和mysql的区别:1、数据模型;2、查询语言;3、扩展性和性能;4、可靠性。本专题为大家提供mongodb和mysql的区别的相关的文章、下载、课程内容,供大家免费下载体验。

280

2023.07.18

mysql密码忘了怎么查看
mysql密码忘了怎么查看

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql密码忘了怎么办呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

513

2023.07.19

mysql创建数据库
mysql创建数据库

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql怎么创建数据库呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

250

2023.07.25

mysql默认事务隔离级别
mysql默认事务隔离级别

MySQL是一种广泛使用的关系型数据库管理系统,它支持事务处理。事务是一组数据库操作,它们作为一个逻辑单元被一起执行。为了保证事务的一致性和隔离性,MySQL提供了不同的事务隔离级别。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

384

2023.08.08

sqlserver和mysql区别
sqlserver和mysql区别

SQL Server和MySQL是两种广泛使用的关系型数据库管理系统。它们具有相似的功能和用途,但在某些方面存在一些显著的区别。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

522

2023.08.11

mysql忘记密码
mysql忘记密码

MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。那么忘记mysql密码我们该怎么解决呢?php中文网给大家带来了相关的教程以及其他关于mysql的文章,欢迎大家前来学习阅读。

594

2023.08.14

桌面文件位置介绍
桌面文件位置介绍

本专题整合了桌面文件相关教程,阅读专题下面的文章了解更多内容。

0

2025.12.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
MySQL 教程
MySQL 教程

共48课时 | 1.5万人学习

MySQL 初学入门(mosh老师)
MySQL 初学入门(mosh老师)

共3课时 | 0.3万人学习

简单聊聊mysql8与网络通信
简单聊聊mysql8与网络通信

共1课时 | 777人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号