> Какую функцию выполняет транзакция (Go)
Уровень: middle · Роль: backend · Категория: Технические вопросы
Компании: YADRO, Kalabi
Стек: Go
> Пример ответа
Короткий ответ
Транзакция - это атомарная последовательность операций с базой данных, которая выполняется как единое целое: либо все операции применяются успешно, либо ни одна. Она гарантирует согласованность данных даже при сбоях, конкурентном доступе и ошибках. Основные свойства транзакции описываются аббревиатурой ACID: atomicity, consistency, isolation, durability. В Go транзакции обычно работают через database/sql и методы Begin, Commit, Rollback.
Подробное объяснение
Транзакция решает три ключевые задачи:
-
Атомарность - если на любом шаге происходит ошибка, все предыдущие изменения откатываются. Это предотвращает частичное обновление данных, например, когда деньги списались с одного счёта, но не зачислились на другой.
-
Изоляция - параллельные транзакции не видят промежуточные состояния друг друга. Уровень изоляции (read committed, repeatable read, serializable) определяет, какие аномалии возможны: dirty read, non-repeatable read, phantom read.
-
Согласованность и долговечность - после 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 нужно повторять транзакцию целиком.
Пример кода
GOfunc 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 - идиоматичный способ гарантировать rollbackdefer 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 - это не работает без координатора.
> Похожие задачи по backend
Назови примеры метрик для алертов
Для чего используется профилирование pprof в Go
Где в памяти живут глобальные переменные в Go?
Когда происходит копирование элементов при передаче массива или слайса в функцию в Go
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью