> Какую функцию выполняет транзакция (Go)

Уровень: middle · Роль: backend · Категория: Технические вопросы

Компании: YADRO, Kalabi

Стек: Go

> Пример ответа

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

Транзакция - это атомарная последовательность операций с базой данных, которая выполняется как единое целое: либо все операции применяются успешно, либо ни одна. Она гарантирует согласованность данных даже при сбоях, конкурентном доступе и ошибках. Основные свойства транзакции описываются аббревиатурой ACID: atomicity, consistency, isolation, durability. В Go транзакции обычно работают через database/sql и методы Begin, Commit, Rollback.

Подробное объяснение

Транзакция решает три ключевые задачи:

  1. Атомарность - если на любом шаге происходит ошибка, все предыдущие изменения откатываются. Это предотвращает частичное обновление данных, например, когда деньги списались с одного счёта, но не зачислились на другой.

  2. Изоляция - параллельные транзакции не видят промежуточные состояния друг друга. Уровень изоляции (read committed, repeatable read, serializable) определяет, какие аномалии возможны: dirty read, non-repeatable read, phantom read.

  3. Согласованность и долговечность - после commit данные гарантированно сохранены, а все бизнес-ограничения (constraints, foreign keys) соблюдены.

В контексте Go важно понимать, что транзакция - это не только про SQL. Она также применима к очередям, кэшам и распределённым системам, но там используются другие механизмы (saga, outbox pattern, двухфазный коммит).

На практике

В Go транзакции работают через *sql.Tx, который получается из *sql.DB. Ключевые моменты:

  • Транзакция должна быть короткой - долгие транзакции блокируют строки и увеличивают вероятность deadlock.
  • Все операции внутри транзакции должны использовать один и тот же *sql.Tx, а не *sql.DB, иначе они не будут частью транзакции.
  • Обязательно вызывать Rollback при ошибке, даже если commit уже не нужен - иначе соединение с БД останется занятым.
  • В Go нет встроенного механизма retry для транзакций - при serialization failure нужно повторять транзакцию целиком.

Пример кода

GO
func transferMoney(ctx context.Context, db *sql.DB, fromID, toID int, amount int) error {
tx, err := db.BeginTx(ctx, nil)
if err != nil {
return err
}
// defer с проверкой на commit - идиоматичный способ гарантировать rollback
defer tx.Rollback()
// списываем
_, err = tx.ExecContext(ctx,
"UPDATE accounts SET balance = balance - $1 WHERE id = $2 AND balance >= $1",
amount, fromID)
if err != nil {
return err
}
// начисляем
_, err = tx.ExecContext(ctx,
"UPDATE accounts SET balance = balance + $1 WHERE id = $2",
amount, toID)
if err != nil {
return err
}
// фиксируем
return tx.Commit()
}

Как отвечать на собеседовании

Начни с определения и ACID, затем переходи к практическим аспектам. Упомяни, что транзакция - это инструмент для обеспечения целостности данных, а не просто "обёртка над SQL". Покажи понимание trade-off: изоляция снижает производительность, поэтому уровень изоляции выбирается под конкретную задачу. Если спросят про распределённые системы - скажи, что там ACID не работает напрямую, и нужны компенсирующие транзакции или saga.

Что проверяет интервьюер

  • Понимание ACID и умение объяснить каждое свойство на примере.
  • Знание, как транзакции реализованы в Go: BeginTx, Commit, Rollback, defer.
  • Понимание проблем конкурентного доступа: lost update, dirty read, phantom read.
  • Умение видеть границы транзакции: что включать внутрь, а что выносить наружу (например, HTTP-запросы нельзя держать внутри транзакции).

Типичные ошибки

  • Забывают вызвать Rollback при ошибке - соединение утекает.
  • Используют db вместо tx внутри транзакции - операции не атомарны.
  • Держат транзакцию открытой во время внешних вызовов (сеть, файловая система) - это блокирует ресурсы БД.
  • Не учитывают уровень изоляции по умолчанию в конкретной СУБД (в PostgreSQL это read committed, в MySQL - repeatable read).
  • Пытаются реализовать распределённую транзакцию через обычный SQL - это не работает без координатора.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью