> Писали ли транзакции в 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 типичный паттерн:

GO
tx, 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 аналогично:

JAVA
try (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 с ручным управлением: аннотация работает только через прокси, и вызов внутри того же класса её не активирует.

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

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