golang 数据库事务 : continue if single exec statement fails

标签 go

我正在编写一个 Go 应用程序,它应该将文件中的数千个值插入到数据库中。这工作正常,只要所有值都可以插入到数据库中。如果其中一个查询失败,之后所有查询都会失败,因为 pq::当前事务被中止,命令被忽略直到事务 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

最佳答案

对于 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) ")

关于golang 数据库事务 : continue if single exec statement fails,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52345294/

相关文章:

go - 将 stdout/stderr 重定向到一个函数的最佳方法是什么,该函数反过来格式化消息并将其打印到控制台?

google-app-engine - 应用引擎推送任务在测试中总是返回 404

go - 我收到一条错误消息,提示没有足够的参数返回

python - 如何将 numpy 数组从 Python 传递给 Golang 函数

mongodb - Azure cosmosDB(mongoDB),如何在 GO lang 或通过 Shell 中禁用集合中的自动索引

go - 在golang中设置测试文件中的变量

xml - 使用 Go 并行读取多个 URL

excel - 在 Google App Engine 上打开 Tealeg xlsx 用 Go 语言创建的 XLSX 文件时出错

Golang RPC 编码自定义函数

docker - 如何为ARM设备构建Docker镜像?