使用golang预处理语句的原始sql事务

1N5*_*818 9 postgresql transactions acid go

我找不到一些可以执行以下三项操作的示例:

1)在golang中允许原始sql事务.

2)使用准备好的陈述.

3)回滚查询失败.

我想做这样的事情,但准备好的陈述.

    stmt, stmt_err := db.Prepare(`
            BEGIN TRANSACTION;

            -- Insert record into first table.

            INSERT INTO table_1 (
                    thing_1,
                    whatever)
            VALUES($1,$2);

            -- Inert record into second table.

            INSERT INTO table_2 (
                    thing_2,
                    whatever)
            VALUES($3,$4);

            END TRANSACTION;
            `)
    if stmt_err != nil {
            return stmt_err
    }   
    res, res_err := stmt.Exec(
            thing_1,
            whatever,
            thing_2,
            whatever)
Run Code Online (Sandbox Code Playgroud)

当我运行它时,我收到此错误: pq: cannot insert multiple commands into a prepared statement

是什么赋予了?是否可以在golang中进行符合ACID的交易?我找不到一个例子.

编辑在这里没有例子.

Yan*_*ozo 14

是Go有很好的sql 事务实现.我们先从交易db.Begin,我们可以结束它tx.Commit如果一切良好或tx.Rollback在错误的情况下.

输入Tx struct {}

Tx是正在进行的数据库事务.

事务必须以对Commit或Rollback的调用结束.

在调用Commit或Rollback之后,对事务的所有操作都失败了ErrTxDone.

通过调用事务的Prepare或Stmt方法为事务准备的语句将通过调用Commit或Rollback来关闭.

另请注意,我们使用事务变量tx.Prepare(...)准备查询

您的功能可能如下所示:

func doubleInsert(db *sql.DB) error {

    tx, err := db.Begin()
    if err != nil {
        return err
    }

    {
        stmt, err := tx.Prepare(`INSERT INTO table_1 (thing_1, whatever)
                     VALUES($1,$2);`)
        if err != nil {
            tx.Rollback()
            return err
        }
        defer stmt.Close()

        if _, err := stmt.Exec(thing_1, whatever); err != nil {
            tx.Rollback() // return an error too, we may want to wrap them
            return err
        }
    }

    {
        stmt, err := tx.Prepare(`INSERT INTO table_2 (thing_2, whatever)
                     VALUES($1, $2);`)
        if err != nil {
            tx.Rollback()
            return err
        }
        defer stmt.Close()

        if _, err := stmt.Exec(thing_2, whatever); err != nil {
            tx.Rollback() // return an error too, we may want to wrap them
            return err
        }
    }

    return tx.Commit()
}
Run Code Online (Sandbox Code Playgroud)

我在这里有一个完整的例子

  • 非常有帮助的帖子,谢谢.但是我不明白,`一个事务必须以对Commit或Rollback的调用结束.当你返回由`tx.Prepare(某些sql ..)引起的错误时,你不执行Commit或rollback .这是为什么?在这种情况下,有问题的交易是否正确关闭?即使没有对基础数据库进行任何更改,我们是否还需要正确关闭事务? (2认同)