Go语言 如何使用jackc/pgx与连接池,上下文,准备好的语句等

juzqafwq  于 2023-09-28  发布在  Go
关注(0)|答案(1)|浏览(224)

我仍然不是一个Maven在golang和仍在学习。这也是我第一次使用PostgreSQL

import "github.com/jackc/pgx/v5/pgxpool"

const DB = "postgres://postgres:xxx@localhost:5432/mydb?pool_min_conns=1&pool_max_conns=5&pool_max_conn_idle_time=30s"

dbpool, err := pgxpool.New(context.Background(), DB)
if err != nil {
    log.Fatal("Unable to create connection pool: "+err.Error())
}
defer dbpool.Close()

1.如何从池中获取连接并使用准备好的语句,其中您将SQL和SQL值作为两个单独的参数传递?

来自PHP,以前从未使用过数据库池。

2.如何确保从池中拉取连接时是“新鲜的”,并且不会继续之前未完成的事务(回滚/提交)?
3.当您释放连接回池时也是如此。如果上下文被取消或请求失败,它会自动进行回滚吗?
4.在请求数据库时如何使用goroutines?是否可以在同一事务中进行并行选择查询,或者所有查询都必须是串行的?我想所有的写查询都必须是串行的?

wbgh16ku

wbgh16ku1#

1.如何从池中获取连接并使用准备好的语句,其中将SQL和SQL值作为两个单独的参数传递?
一般来说你不会。池负责连接的管理(获取和释放)以及准备好的语句的管理(创建和缓存)。
但是,如果您希望保持控制,那么您可以通过使用Acquire方法或任何相关方法显式地从池中获取连接。
类似地,如果你想手动创建和重用一个准备好的语句(例如,你需要在一个紧密的循环中执行相同的查询,但你不想依赖于池对准备好的语句的缓存),那么你可以使用获取的连接的Conn方法,它返回连接的*pgx.Conn表示,并且它有一个名为Prepare的方法。
1.如何确保当你从池中拉取一个连接时是“新鲜的”,并且你不会继续之前未完成的事务(回滚/提交)?
池的Acquire方法返回 available 连接。正在使用的连接,即根据定义,未发布的数据不可用,并且不会由Acquire方法返回。
1.当您释放回池的连接时也是如此。如果上下文被取消或请求失败,它会自动进行回滚吗?
被释放回池的连接所持有的资源,如果不是空闲的,将被 * 销毁 。关于事务提交/回滚,它们都不会被自动调用,文档明确指出: “必须对返回的事务调用提交或回滚,以完成事务块。"*
1.如何在请求数据库时使用goroutines?是否可以在同一事务中进行并行选择查询,或者所有查询都必须是串行的?我想所有的写查询都必须是串行的?
该池可安全地同时使用。然而,pgxpool.Connpgxpool.Tx都不能安全地同时使用。

示例:

Begin不支持自动回滚或自动提交,您必须自己调用RollbackCommit来“完成事务块”。

func f(ctx context.Context, pool *pgxpool.Pool) (err error) {
    tx, err := pool.Begin(ctx)
    if err != nil {
        return err
    }
    defer func() {
        if err != nil {
            tx.Rollback(ctx)
        } else {
            tx.Commit(ctx)
        }
    }()

    _, err := tx.Exec(ctx, "insert into users (email) values ($1)", "[email protected]")
    if err != nil {
        return err
    }

    var id int
    row := tx.QueryRow(ctx, "select id from users where email = $1", "[email protected]")
    if err := row.Scan(&id); err != nil {
        return err
    }

    // NOTE: the above is just an example, if you need the auto
    // generated id of an inserted record, please use the RETURNING
    // clause supported by PostgreSQL.
    return nil
}

但是,如果您希望pgx为您提供RollbackCommit事务,则可以使用BeginFunc

func f(ctx context.Context, pool *pgxpool.Pool) (err error) {
    return pool.BeginFunc(ctx, func(tx pgx.Tx) error {
        _, err := tx.Exec(ctx, "insert into users (email) values ($1)", "[email protected]")
        if err != nil {
            return err
        }

        var id int
        row := tx.QueryRow(ctx, "select id from users where email = $1", "[email protected]")
        if err := row.Scan(&id); err != nil {
            return err
        }

        // NOTE: the above is just an example, if you need the auto
        // generated id of an inserted record, please use the RETURNING
        // clause supported by PostgreSQL.
        return nil
    })
}

相关问题