为了账号安全,请及时绑定邮箱和手机立即绑定

golang 数据库事务:如果单个 exec 语句失败则继续

golang 数据库事务:如果单个 exec 语句失败则继续

Go
暮色呼如 2023-04-04 15:34:36
我正在编写一个 Go 应用程序,它应该将文件中的数千个值插入到数据库中。这工作正常,只要所有值都可以插入到数据库中。如果其中一个查询失败,则之后的所有查询都会失败,因为pq: : current transaction is aborted, commands ignored until end of transaction block我想插入所有元素,如果一个元素的插入失败,应该跳过它并插入其他元素。我的代码:func (db *Database) Insert(values []Value) (transerr error) {    tx, err := db.Begin()    if transerr != nil {        return nil, err    }    defer func() {        if err != nil {            tx.Rollback()        } else {            tx.Commit()        }    }    stmt, err := tx.Prepare("INSERT INTO foo VALUES (?)")    if err != nil {        return err    }    defer stmt.Close()    for _, value : range values {        _, err = stmt.Exec(value)        if err != nil {            log.Error(err)        }    }    return nil}我试图添加一个 tx.Rollback() 以防 stmt.Exec 失败——但这会导致sql: statement is closed.
查看完整描述

2 回答

?
斯蒂芬大帝

TA贡献1827条经验 获得超8个赞

对于 Postgresql,您可以使用ON CONFLICT DO NOTHING


我已经在我这边用 postgresql db 尝试了下面的代码,它忽略了有错误的插入行。我做了一些其他的改变来尝试在我这边。您可以忽略我的其他更改。


func insert(db *sql.DB, values []string) error {

    tx, err := db.Begin()

    if err != nil {

        return err

    }

    defer tx.Commit()

    stmt, err := tx.Prepare("INSERT INTO foo (  foo_col) VALUES ($1) ON CONFLICT DO NOTHING")


    if err != nil {

        fmt.Println("errro at stmt", err)

        return err

    }


    defer stmt.Close()


    for _, value := range values {

        _, err = stmt.Exec(value)

        if err != nil {

            fmt.Println(value, err)

        }

    }

    return nil

}

对于 mysql,你可以使用INSERT IGNORE


stmt, err := tx.Prepare("INSERT IGNORE INTO foo (  foo_col) VALUES ($1) ")


查看完整回答
反对 回复 2023-04-04
?
翻过高山走不出你

TA贡献1875条经验 获得超3个赞

我对该问题的解决方案如下所示:

  • 不要创建单个事务并将所有语句添加到其中,而只是运行它而不创建事务。

  • 当值被读入时,生成新的 go 例程并让事务并行运行(注意连接限制)。

  • 没有并行化,性能下降了大约 30%(从 25k 值的 20s 到 30s——我们之前没有使用并行化)。

  • 通过并行化,性能提高了大约 4 倍(达到 5 秒)——请注意保持在连接范围内


查看完整回答
反对 回复 2023-04-04
  • 2 回答
  • 0 关注
  • 173 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信