> Писали ли транзакции в SQL (Go)
Уровень: middle · Роль: backend · Язык: Go · Категория: Технические вопросы
Компании: BetBoom
Стек: Go, Java
> Пример ответа
Короткий ответ
Да, транзакции в SQL писать приходилось. Обычно это BEGIN, затем несколько INSERT/UPDATE/DELETE, и завершение через COMMIT или ROLLBACK при ошибке. В Go чаще всего использовал database/sql с db.BeginTx, в Java - Connection.setAutoCommit(false) или Spring @Transactional. Главное - гарантировать атомарность и не забывать про откат при любой ошибке.
Подробное объяснение
Транзакция в SQL - это набор операций, который выполняется как единое целое. Если хотя бы одна операция падает, все изменения откатываются. Это критично для целостности данных: например, при переводе денег между счетами нельзя списать с одного счёта и не зачислить на другой.
В Go стандартная библиотека database/sql предоставляет BeginTx, который принимает context.Context и sql.TxOptions. Внутри транзакции вы получаете *sql.Tx и выполняете запросы через него. По завершении вызываете tx.Commit() или tx.Rollback(). Важно: Rollback после Commit не ошибка, но лучше использовать defer tx.Rollback() с проверкой ошибки.
В Java с JDBC управление транзакцией идёт через Connection. По умолчанию auto-commit включён, поэтому его отключают. В Spring Framework аннотация @Transactional управляет транзакцией декларативно, но нужно понимать propagation и isolation levels.
Уровни изоляции (READ COMMITTED, REPEATABLE READ, SERIALIZABLE) влияют на конкурентность и аномалии. В Go можно задать sql.LevelSerializable в TxOptions. В Java - через Connection.TRANSACTION_SERIALIZABLE.
На практике
На практике чаще всего использовал транзакции для:
- Финансовых операций (списание/зачисление).
- Создания связанных записей (заказ + позиции заказа).
- Миграций данных, где важна атомарность.
В Go с database/sql типичный паттерн:
GOtx, err := db.BeginTx(ctx, nil)if err != nil { return err }defer tx.Rollback()_, err = tx.ExecContext(ctx, "UPDATE accounts SET balance = balance - $1 WHERE id = $2", amount, from)if err != nil { return err }_, err = tx.ExecContext(ctx, "UPDATE accounts SET balance = balance + $1 WHERE id = $2", amount, to)if err != nil { return err }return tx.Commit()
Здесь defer tx.Rollback() сработает, если Commit не был вызван. В Java с JDBC аналогично:
JAVAtry (Connection conn = dataSource.getConnection()) {conn.setAutoCommit(false);try (PreparedStatement ps = conn.prepareStatement("UPDATE ...")) {// ...conn.commit();} catch (SQLException e) {conn.rollback();throw e;}}
В Spring достаточно @Transactional на методе сервиса.
Как отвечать на собеседовании
Стоит сказать, что транзакции использовал, и привести конкретный пример: перевод средств или создание заказа. Упомянуть, что в Go работал с database/sql и BeginTx, в Java - с JDBC и Spring @Transactional. Подчеркнуть, что всегда обрабатывал откат при ошибках и понимаю разницу между уровнями изоляции. Если спросят про вложенные транзакции, можно рассказать про savepoint или propagation в Spring.
Что проверяет интервьюер
Интервьюер хочет убедиться, что кандидат:
- Понимает, зачем нужны транзакции (ACID).
- Умеет писать код с
BEGIN/COMMIT/ROLLBACKна практике. - Знает особенности работы с транзакциями в Go и Java.
- Осознаёт риски: deadlock, долгие транзакции, уровни изоляции.
- Не забывает про обработку ошибок и откат.
Типичные ошибки
- Забыть вызвать
Rollbackпри ошибке - транзакция остаётся открытой, блокируя ресурсы. - Использовать
defer tx.Rollback()без проверки ошибкиCommit- можно не заметить, что коммит не прошёл. - Слишком длинные транзакции, которые держат блокировки и снижают производительность.
- Игнорирование уровней изоляции - например, использование
READ COMMITTEDтам, где нужнаSERIALIZABLE. - В Java забыть вернуть
autoCommitвtrueпосле ручного управления, если соединение переиспользуется. - Путать
@Transactionalв Spring с ручным управлением: аннотация работает только через прокси, и вызов внутри того же класса её не активирует.
> Похожие задачи по Go
Какие принципы построения REST API существуют?
Что такое синхронное программирование?
Какие интересные задачи были на предыдущих работах
Приведите пример улучшения процессов тестирования в команде
> Похожие задачи по backend
Какие принципы построения REST API существуют?
Что такое синхронное программирование?
Какие интересные задачи были на предыдущих работах
Приведите пример улучшения процессов тестирования в команде
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью