如何在事务回滚时添加一些操作

huangapple go评论89阅读模式
英文:

How to add some operations on transaction rollback

问题

// 更新 CloseJira 状态到数据库中

问题陈述 - Golang 如何在回滚触发时调用 autogeneratedjiraclose() 函数以运行某些操作。

func CloseJira(qMonName string) {
    tx, err := dbCon.Begin()
    notifier.CheckErr(err, "CloseJira() -> tx -> dbCon.Begin()", dbErrLog)
    defer tx.Rollback()

    stmt, errDBPrepare := tx.Prepare("update TABLE1 set Key=NULL, StatusKey='Closed', Statustime_UTC=? where Name=?")
    // 更新数据库表记录
    notifier.CheckErr(errDBPrepare, "updateCloseJira() -> dbCon.Prepare()", dbErrLog)
    defer stmt.Close() // 危险!

    res, errStmtExec := stmt.Exec(time.Now().UTC(), qMonName)
    notifier.CheckErr(errStmtExec, "CloseJira() -> stmt.Exec()", dbErrLog)

    err = tx.Commit()
    notifier.CheckErr(err, "CloseJira() -> err -> tx.Commit()", dbErrLog)

    _, errRowAffected := res.RowsAffected()
    notifier.CheckErr(errRowAffected, "CloseJira() -> res.RowsAffected()", dbErrLog)
}
英文:

// update the CloseJira status into the database

Problem Statement - Golang how and where to call autogeneratedjiraclose() function to run some operation if rollback trigger.

func CloseJira(qMonName string) {
tx, err := dbCon.Begin()
notifier.CheckErr(err, "CloseJira() -> tx -> dbCon.Begin()", dbErrLog)
defer tx.Rollback()

stmt, errDBPrepare := tx.Prepare("update TABLE1 set 
Key=NULL, StatusKey='Closed', Statustime_UTC=? where Name=?") 
//Update db table record
notifier.CheckErr(errDBPrepare, "updateCloseJira() -> dbCon.Prepare()", 
dbErrLog)
defer stmt.Close() // danger!

res, errStmtExec := stmt.Exec(time.Now().UTC(), qMonName)
notifier.CheckErr(errStmtExec, "CloseJira() -> stmt.Exec()", dbErrLog)

err = tx.Commit()
notifier.CheckErr(err, "CloseJira() -> err -> tx.Commit()", dbErrLog)

_, errRowAffected := res.RowsAffected()
notifier.CheckErr(errRowAffected, "CloseJira() -> res.RowsAffected()", 
dbErrLog)
}

答案1

得分: 2

这是我在需要进行事务时经常使用的模式:

func Foo() (err error) {
    var tx *sql.Tx
    tx, err = db.Begin()
    if err != nil {
        return err
    }
    defer func() {
        if err == nil {
            tx.Commit()
        } else {
            tx.Rollback()
        }
    }()
    // 在这里进行你想要的任何操作。
}

关键在于,这里的延迟函数将始终在最后运行。如果你的函数返回一个错误,你可以获取它并回滚事务(以及采取任何其他你想要的操作),如果函数正常返回,你可以提交事务。

英文:

Here is pattern I use often when I need a transaction:

func Foo() (err error) {
    var tx *sql.Tx
    tx, err = db.Begin()
    if err != nil {
        return err
    }
    defer func() {
        if err == nil {
            tx.Commit()
        } else {
            tx.Rollback()
        }
    }()
    // Do whatever you want here.
}

The trick is that here, the deferred function will always run at the end. If your function returns with an error, you can get it and rollback (and take whatever other action you want to), and if the function returns normally, you can commit the transaction.

huangapple
  • 本文由 发表于 2017年6月28日 16:05:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/44796893.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定