Вступить в клуб →
сложнаявопросPostgreSQL и Redis: запросы и кэш

Распределённый лок в Redis снимается чужим владельцем

Лок на обработку заказа реализован так:

ok, _ := rdb.SetNX(ctx, "lock:order:"+id, "1", 30*time.Second).Result()
if !ok {
    return ErrBusy
}
defer rdb.Del(ctx, "lock:order:"+id)

processOrder(ctx, id) // обычно 2 с, изредка — больше 30 с

В проде изредка встречаются два одновременно работающих обработчика одного заказа. Что нужно изменить в первую очередь?

  • Просто увеличить TTL лока до часа — тогда он гарантированно не успеет истечь во время самой долгой обработки
  • Перенести лок в PostgreSQL: корректную взаимную блокировку даёт только транзакционная БД, а Redis для этого непригоден
  • Записывать в лок уникальный токен владельца и снимать его атомарно Lua-скриптом, сверив токен; долгую обработку сопровождать продлением TTL
  • Убрать TTL совсем: лок должен сниматься только явным `Del` после обработки, тогда чужой владелец его не перехватит

🔒 Проверка ответа — для участников клуба

  • Проверка ответа
  • Подсказка, если застряли
  • Разбор с объяснением, почему так
  • Прогресс по всем задачам и виртуальные собеседования
Зарегистрироваться →

Регистрация занимает минуту

Другие задачи раздела