Вопрос проверяет знание механизма блокировки строк при конкурентном доступе к данным.
SELECT FOR UPDATE блокирует выбранные строки от изменений другими транзакциями. Это полезно при реализации очередей задач или других сценариев, где важно гарантировать эксклюзивную работу с данными.
SELECT ... FOR UPDATE — это способ получить эксклюзивную блокировку на строки, участвующие в выборке. До завершения транзакции эти строки не могут быть изменены другими транзакциями.
Строка блокируется сразу после выборки
Другие транзакции, которые попытаются заблокировать ту же строку — будут ждать или получат ошибку
Пример:
BEGIN;
SELECT * FROM email_tasks WHERE is_sent = false ORDER BY created_at LIMIT 1 FOR UPDATE;
-- Отправка письма
UPDATE email_tasks SET is_sent = true WHERE id = @id;
COMMIT;В C# через Dapper или EF Core:
using var tx = db.Database.BeginTransaction();
var task = db.EmailTasks
.FromSqlRaw("SELECT * FROM email_tasks WHERE is_sent = false FOR UPDATE")
.FirstOrDefault();
// отправка
task.IsSent = true;
db.SaveChanges();
tx.Commit();Очереди задач
Распределённая обработка писем, уведомлений
Защита от конкурентных изменений
Когда использовать:
При высокой конкуренции и необходимости гарантировать, что один объект обрабатывается только одним процессом