Sobes.tech
Back to questions
Middle — Middle+
79

Каким образом управлять транзакциями внутри одного метода, когда используется несколько транзакционных операций, с учетом контекста выполнения?

Answer from AI

sobes.tech AI

В Go для управления транзакциями внутри одного метода с несколькими транзакционными операциями обычно используют объект транзакции, полученный из контекста базы данных (например, *sql.Tx). Важно передавать этот объект в каждую функцию, которая выполняет операции с БД, чтобы все они были частью одной транзакции.

Пример:

func doComplexOperation(db *sql.DB) error {
    tx, err := db.Begin()
    if err != nil {
        return err
    }
    defer func() {
        if p := recover(); p != nil {
            tx.Rollback()
            panic(p)
        } else if err != nil {
            tx.Rollback()
        } else {
            err = tx.Commit()
        }
    }()

    err = operation1(tx)
    if err != nil {
        return err
    }

    err = operation2(tx)
    if err != nil {
        return err
    }

    return nil
}

func operation1(tx *sql.Tx) error {
    // Выполнение SQL-запросов через tx.Exec или tx.Query
    return nil
}

func operation2(tx *sql.Tx) error {
    // Аналогично
    return nil
}

Таким образом, все операции выполняются в рамках одной транзакции, и при ошибке происходит откат. Контекст выполнения (context.Context) можно использовать для отмены или таймаута, передавая его в методы запросов, но сам объект транзакции должен передаваться явно.