微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

database / sql Tx – 检测提交或回滚

使用数据库/ sql和驱动程序包和Tx,似乎无法检测事务是否已提交或回滚,而不尝试另一个事件并因此而收到错误,然后检查错误以确定错误.我想能够从Tx对象确定是否进行.当然,我可以在使用Tx的函数中定义和设置另一个变量,但是我有相当多的它们,每次都是次数(变量和赋值).如果需要,我还有一个延迟函数来执行Rollback,并且需要传递bool变量.
在提交或回滚之后将Tx变量设置为n可以接受,并且GC将恢复任何内存,或者是否否,还是有更好的选择?

解决方法

为什么你甚至需要这样做?调用Begin()的函数也应该调用Commit()或Rollback()并返回一个适当的错误.

例如,此代码根据是否返回错误执行提交或回滚:

func (s Service) DoSomething() (err error) {
    tx,err := s.db.Begin()
    if err != nil {
        return
    }
    defer func() {
        if err != nil {
            tx.Rollback()
            return
        }
        err = tx.Commit()
    }()
    if _,err = tx.Exec(...); err != nil {
        return
    }
    if _,err = tx.Exec(...); err != nil {
        return
    }
    // ...
    return
}

请注意我如何检查错误,看我是否应该提交或回滚.然而,上述示例并不处理恐慌.

我不喜欢在每个数据库例程上执行提交/回滚逻辑,所以我通常将它们包装在一个事务处理程序中.一些这样的事情:

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 {
            switch p := p.(type) {
            case error:
                err = p
            default:
                err = fmt.Errorf("%s",p)
            }
        }
        if err != nil {
            tx.Rollback()
            return
        }
        err = tx.Commit()
    }()
    err = txFunc(tx)
    return err
}

这样我就可以做到这一点:

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
        }
    })
}

请注意,如果我的事务中的任何事情都是混乱,它将被事务处理程序自动处理.

在我的实际实现中,我传递一个接口而不是* sql.Tx,以防止对Commit()或Rollback()的不必要的调用.

这是一个简单的代码段,用于演示延迟工作方式(打印4,而不是5):

package main

func test() (i int) {
    defer func() {
        i = 4
    }()
    return 5
}

func main() {
    println(test())
}

http://play.golang.org/p/0OinYDWFlx

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐