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

golang数据库事务:如果单个exec语句失败,则继续,go,Go,我正在编写一个Go应用程序,它可以将文件中的数千个值插入数据库。只要所有的值都可以插入到数据库中,这就可以正常工作。如果其中一个查询失败,则随后的所有查询都会失败,因为pq::当前事务被中止,忽略命令直到事务块结束 我想插入所有元素,如果某个元素的插入失败,则应跳过该元素,并插入其他元素 我的代码: func (db *Database) Insert(values []Value) (transerr error) { tx, err := db.Begin() if tran

我正在编写一个Go应用程序,它可以将文件中的数千个值插入数据库。只要所有的值都可以插入到数据库中,这就可以正常工作。如果其中一个查询失败,则随后的所有查询都会失败,因为
pq::当前事务被中止,忽略命令直到事务块结束

我想插入所有元素,如果某个元素的插入失败,则应跳过该元素,并插入其他元素

我的代码:

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关闭

对于Postgresql,您可以在冲突上使用什么都不做

我用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,您可以使用插入忽略

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

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

  • 不要创建单个事务并向其中添加所有语句,而只运行它而不创建事务
  • 在读入值时,生成新的go例程,并让事务并行运行(注意连接限制)
  • 在没有并行化的情况下,性能下降了约30%(从25k值的20秒下降到30秒-我们以前没有使用并行化)
  • 通过并行化,性能提高了大约4倍(到5秒)——只需注意保持在连接范围内即可

我建议对查询进行结构化处理,这样就不会出现这些类型的错误,但无论如何。。。底层的数据库技术是什么?数据库是MySQL/PostgreSQL-构造查询非常困难,因为输入是随机的-但我会尝试一下,谢谢提示!插入失败是由于
INSERT
ed值与数据库中已存在的其他行(例如
UNIQUE
索引)上的约束冲突,还是由于某些其他问题?事务的要点是确保执行所有或无任何语句。这不是你想要的。不必为事务操心。数据彼此不相关-数据库只是一个存储器,数据彼此不相关。我考虑过不使用事务-这对性能有影响吗?谢谢你的回答:)