Что такое транзакция · Golang Backend — JobPilot

Что такое транзакция

Golang Backend · 20%
Вопрос 2926 / #
Пример ответа

Коротко: В моём опыте разработки на 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 при панике, утечки соединений из-за незакрытых транзакций или неправильная обработка контекста.
Практический совет (на неделю):
  1. Всегда используйте defer с Rollback в транзакциях Go для гарантированного отката при ошибках.
  2. Тестируйте транзакции в изолированной среде, например, с тестовыми контейнерами Docker, чтобы избежать побочных эффектов.
Golang Backend
Общий
20%
Навигация
Что такое GIL в Python
Следующий: Что такое контекстный менеджер в Python
Предыдущий: Что такое GIL в Python

Мы используем cookie для улучшения сайта. Продолжая пользоваться сайтом, вы соглашаетесь с политикой cookie и политикой конфиденциальности.