Sobes.tech
Middle — Middle+

Как да управляваме транзакциите в рамките на един метод, когато се използват няколко транзакционни операции, като се вземе предвид контекста на изпълнение?

sobes.tech AI

Отговор от 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
}

По този начин всички операции се изпълняват в рамките на една транзакция, и при грешка се извършва rollback. Контекстът за изпълнение (context.Context) може да се използва за анулиране или задаване на таймаут, като се предава към методите за заявки, но обектът на транзакцията трябва да се предава явно.