Вопрос проверяет понимание механизма пропуска заблокированных строк в SQL для конкурентного доступа.
SKIP LOCKED — это расширение SQL, доступное в PostgreSQL (начиная с версии 9.5) и некоторых других СУБД, которое модифицирует поведение команды SELECT FOR UPDATE. Обычно SELECT FOR UPDATE блокирует выбранные строки до завершения транзакции, и если другая транзакция пытается заблокировать те же строки, она ждет. SKIP LOCKED заставляет запрос пропустить уже заблокированные строки и вернуть только те, которые свободны.
Этот механизм особенно полезен в системах с очередями задач, где несколько воркеров одновременно выбирают задачи для обработки. Без SKIP LOCKED воркеры могут конкурировать за одни и те же строки, вызывая задержки. С SKIP LOCKED каждый воркер получает уникальный набор задач без блокировок.
-- Создаем таблицу задач
CREATE TABLE tasks (
id SERIAL PRIMARY KEY,
status TEXT DEFAULT 'pending',
payload TEXT
);
-- Вставляем тестовые данные
INSERT INTO tasks (payload) VALUES ('task1'), ('task2'), ('task3');
-- Первая транзакция блокирует одну задачу
BEGIN;
SELECT * FROM tasks WHERE status = 'pending' LIMIT 1 FOR UPDATE;
-- Не завершаем транзакцию
-- Вторая транзакция использует SKIP LOCKED
BEGIN;
SELECT * FROM tasks WHERE status = 'pending' LIMIT 1 FOR UPDATE SKIP LOCKED;
-- Вернет другую задачу, пропустив заблокированную
COMMIT;SKIP LOCKED — мощный инструмент для построения высокопроизводительных конкурентных систем, где важна параллельная обработка данных без взаимных блокировок. Его стоит применять в очередях, пулах ресурсов и любых сценариях с множеством потребителей, работающих с общим набором строк.