Пример ответа
Коротко: В моём опыте разработки на Go, транзакция — это атомарная операция, которая либо полностью выполняется, либо полностью откатывается, обеспечивая целостность данных, особенно в базах данных.
Ключевые идеи:
- Транзакция гарантирует ACID-свойства: атомарность, согласованность, изоляцию и долговечность.
- В Go я использую транзакции через драйверы баз данных, такие как database/sql с pgx для PostgreSQL.
- Транзакции предотвращают частичные обновления данных, что критично для финансовых или многопользовательских систем.
Пример: При обработке платежа в банковском приложении: списание с одного счёта и зачисление на другой должны выполняться как единая транзакция — если одно действие падает, оба откатываются.
Пример транзакции в Go с использованием database/sql для перевода средств между счетами
go
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/lib/pq"
)
func transferFunds(db *sql.DB, fromID, toID int, amount float64) error {
tx, err := db.Begin()
if err != nil {
return fmt.Errorf("failed to begin transaction: %v", err)
}
defer func() {
if p := recover(); p != nil {
tx.Rollback()
panic(p)
}
}()
_, err = tx.Exec("UPDATE accounts SET balance = balance - $1 WHERE id = $2", amount, fromID)
if err != nil {
tx.Rollback()
return fmt.Errorf("failed to debit account: %v", err)
}
_, err = tx.Exec("UPDATE accounts SET balance = balance + $1 WHERE id = $2", amount, toID)
if err != nil {
tx.Rollback()
return fmt.Errorf("failed to credit account: %v", err)
}
if err := tx.Commit(); err != nil {
return fmt.Errorf("failed to commit transaction: %v", err)
}
return nil
}
func main() {
db, err := sql.Open("postgres", "host=localhost user=postgres dbname=bank sslmode=disable")
if err != nil {
log.Fatal(err)
}
defer db.Close()
if err := transferFunds(db, 1, 2, 100.0); err != nil {
log.Printf("Transfer failed: %v", err)
} else {
log.Println("Transfer successful")
}
}
Вопросы для интервьюера:
- Как вы управляете изоляцией транзакций в Go? — Я настраиваю уровни изоляции через txOptions в database/sql, например, sql.LevelSerializable для предотвращения гонок.
- Какие ошибки чаще всего возникают при работе с транзакциями в Go? — Типичные ошибки: забытый Rollback при панике, утечки соединений из-за незакрытых транзакций или неправильная обработка контекста.
Практический совет (на неделю):
- Всегда используйте defer с Rollback в транзакциях Go для гарантированного отката при ошибках.
- Тестируйте транзакции в изолированной среде, например, с тестовыми контейнерами Docker, чтобы избежать побочных эффектов.
Golang Backend
Общий
20%
Следующий: Что такое контекстный менеджер в Python
Предыдущий: Что такое GIL в Python