MySQL的for update skip locked
最近有一个功能要是音频转文字以及翻译,该任务不仅耗时还消耗硬件,在硬件能够支持的情况下可以启动多台电脑一起处理任务加快速度,启动多个程序会出现处理同一个任务的问题,也就是并发的问题,趁机了解了一下mysql的
FOR UPDATE SKIP LOCKED
在 MySQL 中,FOR UPDATE SKIP LOCKED
是一个强大的功能,通常用于解决并发环境中的任务分配问题,确保每个任务只被一个进程处理。它允许查询未被锁定的记录,并跳过那些已经被其他事务锁定的记录。
FOR UPDATE SKIP LOCKED
解释
FOR UPDATE
:锁定查询到的行,防止其他事务对这些行进行修改。SKIP LOCKED
:跳过那些已经被其他事务锁定的行,返回未被锁定的记录。
这种方法非常适用于任务队列场景,可以避免任务被多个进程同时处理。
MySQL 8.0+ 示例
假设我们有一个任务表 tasks
,其中包含任务的状态。
任务表结构
CREATE TABLE tasks ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(255), status INT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP );
状态含义
status = 1
:任务待处理status = 2
:任务正在处理中status = 3
:任务已完成
查询并锁定未处理的任务
我们可以使用 FOR UPDATE SKIP LOCKED
查询并锁定待处理的任务。此查询会锁定一行记录,如果该记录已被其他事务锁定,则跳过该记录,返回未被锁定的记录。
查询并锁定任务
START TRANSACTION; SELECT id, name FROM tasks WHERE status = 1 FOR UPDATE SKIP LOCKED LIMIT 1;
这个查询将:
- 锁定一个
status = 1
(待处理)的任务。 - 如果该任务已经被其他事务锁定,它将跳过这行记录,返回一个未被锁定的任务。
- 通过
LIMIT 1
限制每次查询一个任务。
更新任务状态
UPDATE tasks SET status = 2, updated_at = NOW() WHERE id = <TASK_ID>; COMMIT;
执行完任务后,更新任务的 status
字段为 2
,表示任务正在处理中,最后提交事务。
Python 使用示例
如果你使用 Python 和 SQLAlchemy 来处理任务,可以像下面这样实现:
from sqlalchemy import create_engine, text from sqlalchemy.orm import sessionmaker # 数据库连接 engine = create_engine("mysql+pymysql://user:password@localhost/database") Session = sessionmaker(bind=engine) def fetch_and_process_task(): with Session() as session: # 查询并锁定任务 task = session.execute( text(""" SELECT id, name FROM tasks WHERE status = 1 FOR UPDATE SKIP LOCKED LIMIT 1 """) ).fetchone() if task: task_id = task.id # 更新任务状态 session.execute( text(""" UPDATE tasks SET status = 2, updated_at = NOW() WHERE id = :task_id """), {"task_id": task_id} ) session.commit() # 模拟任务处理 print(f"Processing task: {task.name}") else: print("No pending tasks available.")
注意事项
- 版本要求:
FOR UPDATE SKIP LOCKED
是 MySQL 8.0 及以上版本的功能,旧版本的 MySQL 不支持此功能。 - 锁定行:使用
FOR UPDATE
锁定的行会阻止其他事务修改该行,直到事务提交。 - 跳过锁定:
SKIP LOCKED
允许跳过已被其他事务锁定的行,确保并发的任务处理不会发生冲突。 - 事务管理:确保在事务内执行
SELECT
和UPDATE
,以保持一致性。
总结
FOR UPDATE SKIP LOCKED
是 MySQL 中用于并发任务处理的有力工具,可以避免任务重复执行。- 适用于分布式任务队列和需要高并发的场景,确保任务不会被多个进程同时处理。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!