首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在一个事务中使用golang执行多个查询的惯用方法

在一个事务中使用golang执行多个查询的惯用方法
EN

Stack Overflow用户
提问于 2015-01-02 11:09:53
回答 2查看 9.9K关注 0票数 4

目前,我(我的第二天)正在努力寻找进行多个查询的最佳方法,并且想知道您是否知道一个解决方案。

我有一个打开的*sql.DB连接,名为myDb,并使用go-sql-驱动程序。

代码语言:javascript
复制
func TruncateGalleryImport() error {

    s := make([]string, 0)

    s = append(s, "TRUNCATE TABLE add_map")
    s = append(s, "TRUNCATE TABLE album")
    s = append(s, "TRUNCATE TABLE album_permission")
    s = append(s, "TRUNCATE TABLE album_view")
    s = append(s, "TRUNCATE TABLE album_watch")
    s = append(s, "TRUNCATE TABLE media")
    s = append(s, "TRUNCATE TABLE media_user_view")
    s = append(s, "TRUNCATE TABLE media_view")
    s = append(s, "TRUNCATE TABLE media_watch")
    s = append(s, "TRUNCATE TABLE private_map")
    s = append(s, "TRUNCATE TABLE attachment")
    s = append(s, "TRUNCATE TABLE attachment_data")

    for _, q := range s {
        _, err := myDb.Exec(q)
        if err != nil {
            return err
        }
    }

    return nil
}

是否可以仅使用一个事务将所有上述查询一起提交?

干杯

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-01-02 11:39:09

使用一个事务,如下所示(参见代码中的注释):

代码语言:javascript
复制
func TruncateGalleryImport() error {
    s := make([]string, 0)

    s = append(s, "TRUNCATE TABLE add_map")
    s = append(s, "TRUNCATE TABLE album")
    s = append(s, "TRUNCATE TABLE album_permission")
    s = append(s, "TRUNCATE TABLE album_view")
    s = append(s, "TRUNCATE TABLE album_watch")
    s = append(s, "TRUNCATE TABLE media")
    s = append(s, "TRUNCATE TABLE media_user_view")
    s = append(s, "TRUNCATE TABLE media_view")
    s = append(s, "TRUNCATE TABLE media_watch")
    s = append(s, "TRUNCATE TABLE private_map")
    s = append(s, "TRUNCATE TABLE attachment")
    s = append(s, "TRUNCATE TABLE attachment_data")

    // Get new Transaction. See http://golang.org/pkg/database/sql/#DB.Begin
    txn, err := myDb.Begin()

    if err != nil {
        return err
    }

    defer func() {
        // Rollback the transaction after the function returns.
        // If the transaction was already commited, this will do nothing.
        _ = txn.Rollback()
    }()

    for _, q := range s {
        // Execute the query in the transaction.
        _, err := txn.Exec(q)

        if err != nil {
            return err
        }
    }

    // Commit the transaction.
    return txn.Commit()
}
票数 8
EN

Stack Overflow用户

发布于 2017-06-13 12:57:28

您可以使用包装函数来执行提交/回滚逻辑,甚至可以使用字符串匹配扩展错误处理。

代码语言:javascript
复制
// RDBTransaction is a function which abstracts a sql transaction
// into a function with an isolation level (isolvl) parameter.
// the following integers represent the available isolation levels (isolvl)
//  1: SERIALIZABLE
//  2: REPEATABLE READ
//  3: READ COMMITTED
//  4: READ UNCOMMITTED
func RDBTransaction(db *sql.DB, isolvl int, fn func(*sql.Tx) error) (err error) {
    var tx *sql.Tx
    tx, err = db.Begin()
    if err != nil {
        return err
    }

    // transaction isolation level setting
    switch isolvl {
    case 1:
        _, err = tx.Exec(`set transaction isolation level serializable`)
    case 2:
        _, err = tx.Exec(`set transaction isolation level repeatable read`)
    case 3:
        _, err = tx.Exec(`set transaction isolation level read committed`)
    case 4:
        _, err = tx.Exec(`set transaction isolation level read uncommitted`)
    default:
        _, err = tx.Exec(`set transaction isolation level serializable`)
    }
    if err != nil {
        return err
    }

    // catch all, commit/rollback
    defer func() {
        if err != nil {
            tx.Rollback()
            return
        }
        err = tx.Commit()
    }()

    // run transaction
    err = fn(tx)

    return err
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27741185

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档