## 使用 SKIP LOCKED 实现非阻塞队列处理
当多个工作进程处理队列时,SKIP LOCKED 允许进程处理不同的行而无需等待。
**错误示例(进程间相互阻塞):**
sql
-- 工作进程 1 和 2 同时尝试获取下一个任务
begin;
select * from jobs where status = 'pending' order by created_at limit 1 for update;
-- 工作进程 2 等待工作进程 1 释放锁!
**正确示例(使用 SKIP LOCKED 进行并行处理):**
sql
-- 每个工作进程跳过已锁定的行并获取下一个可用行
begin;
select * from jobs
where status = 'pending'
order by created_at
limit 1
for update skip locked;
-- 工作进程 1 获取任务 1,工作进程 2 获取任务 2(无需等待)
update jobs set status = 'processing' where id = $1;
commit;
完整的队列模式:
sql
-- 在一个语句中完成原子声明和更新
update jobs
set status = 'processing', worker_id = $1, started_at = now()
where id = (
select id from jobs
where status = 'pending'
order by created_at
limit 1
for update skip locked
)
returning *;
参考:[SELECT FOR UPDATE SKIP LOCKED](https://www.postgresql.org/docs/current/sql-select.html#SQL-FOR-UPDATE-SHARE)
数据来源:claude-code-templates(MIT),中文翻译由 AI 生成。详见关于我们。