Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Задачи

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

AI info

Карта сайта

Документы

Медиа

Назад
Вопрос про Golang: transaction, locking, balance, race condition

Как предотвратить списание средств с баланса при гонке транзакций?

Проверяет знание транзакций на практическом примере.

Короткий ответ

Нужно использовать транзакции с блокировкой строк (SELECT FOR UPDATE), чтобы избежать одновременного изменения баланса разными транзакциями.

Длинный ответ

Проблема: если две транзакции одновременно списывают деньги, они могут прочитать одинаковое значение баланса и превысить лимит.

Решения:

  1. Транзакция + SELECT FOR UPDATE — блокирует строку:

BEGIN;
SELECT balance FROM accounts WHERE id = 1 FOR UPDATE;
-- проверка баланса и UPDATE
COMMIT;
  1. Проверка и обновление в одном запросе:

UPDATE accounts
SET balance = balance - 100
WHERE id = 1 AND balance >= 100;
  • Если обновлено 0 строк — недостаточно средств или параллельная транзакция победила.

  • Этот подход атомарен.

  1. Уровень изоляции Repeatable Read или выше — для защиты от фантомных чтений, если запрос зависит от агрегатов.

Вывод:

  • Лучшее решение — атомарный UPDATE с проверкой условий в одном запросе.

  • SELECT FOR UPDATE подходит, если логика сложнее и требует промежуточных вычислений.

  • Аватар

    Golang Guru

    Maxim Lukyanov

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.

Уровень

  • Рейтинг:

    5

  • Сложность:

    8

Навыки

  • Golang

    Golang

  • Postgres

    Postgres

Ключевые слова

#transaction

#locking

#balance

#race condition

Подпишись на Golang Developer в телеграм

  • Аватар

    Golang Guru

    Maxim Lukyanov

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.