Maison >développement back-end >Golang >Comment puis-je détecter de manière fiable la validation ou l'annulation d'une transaction de base de données dans le package « database/sql » de Go ?

Comment puis-je détecter de manière fiable la validation ou l'annulation d'une transaction de base de données dans le package « database/sql » de Go ?

Patricia Arquette
Patricia Arquetteoriginal
2024-12-22 18:44:11587parcourir

How Can I Reliably Detect Database Transaction Commit or Rollback in Go's `database/sql` Package?

Détection de la validation ou de l'annulation de transaction dans la base de données/sql

Dans le package base de données/sql avec son interface de pilote et son type Tx, ce n'est pas le cas explicitement possible de déterminer si une transaction a été validée ou annulée sans tenter une autre transaction. L'erreur renvoyée par la tentative suivante peut ensuite être examinée pour déduire l'état de la transaction.

Pour éviter une surcharge supplémentaire, on peut envisager de définir la variable Tx sur zéro après une validation ou une restauration. Cependant, cette approche est généralement déconseillée car elle peut entraîner un comportement inattendu et des fuites de mémoire.

Une solution recommandée consiste à utiliser un gestionnaire de transactions pour envelopper la logique de transaction. Cela garantit que les appels Begin(), Commit() et Rollback() se trouvent toujours dans la même fonction, simplifiant ainsi le suivi et garantissant une gestion appropriée des transactions à l'aide d'instructions defer.

Par exemple :

func Transact(db *sql.DB, txFunc func(*sql.Tx) error) (err error) {
    tx, err := db.Begin()
    if err != nil {
        return
    }
    defer func() {
        if p := recover(); p != nil {
            tx.Rollback()
            panic(p) // re-throw panic after Rollback
        } else if err != nil {
            tx.Rollback() // err is non-nil; don't change it
        } else {
            err = tx.Commit() // err is nil; if Commit returns error update err
        }
    }()
    err = txFunc(tx)
    return err
}

Avec ce gestionnaire, la logique de transaction peut être encapsulée comme suit :

func (s Service) DoSomething() error {
    return Transact(s.db, func (tx *sql.Tx) error {
        if _, err := tx.Exec(...); err != nil {
            return err
        }
        if _, err := tx.Exec(...); err != nil {
            return err
        }
        return nil
    })
}

Cette approche maintient le code de transaction concis et garantit une gestion cohérente. Notez que le gestionnaire de transactions utilise recovery() pour intercepter les paniques et lance rapidement une restauration. Cependant, il convient de souligner qu'il est préférable de renvoyer des erreurs plutôt que de paniquer.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn