gpt4 book ai didi

postgresql - Golang - pgbouncer 和事务使用

转载 作者:IT王子 更新时间:2023-10-29 00:46:35 25 4
gpt4 key购买 nike

技术细节

  • 转到版本 1.2
  • go bmizerany/pq 的 postrgres 库

这个问题让我很生气,我希望有人能够提供帮助。

我在 golang 中开发了一个应用程序来从 postgres 数据库读取数据,并为每条记录发出一个 http 请求,然后更新数据库。

这一切都很简单。但是,我们有 pgbouncer。我们对 pgbouncer 的配置是这样的,它不支持准备好的语句。 Go 静默地将所有查询包装在准备好的语句中。 pgbouncer 的解决方法是设置事务。这对于插入/更新/删除之类的事情来说都很好。

对于 select 语句,我将其包装在事务中:

func TransactionQuery(db *sql.DB, baseQuery string) (rows *sql.Rows, code int, err error) {
tx, txErr := db.Begin()
if txErr != nil {
return nil, -1, txErr
}

selectStmt, prepErr := tx.Prepare(baseQuery)
if prepErr != nil {
return nil, -1, fmt.Errorf("Failed to prepare statment: %s Error: %v", baseQuery, prepErr)
}

defer func() {
if stmtErr := selectStmt.Close(); stmtErr != nil {
rows = nil
code = -2
err = fmt.Errorf("Failed to close statement: %v.", stmtErr)
}
}()

rows, err = selectStmt.Query()
if err != nil {
fmt.Errorf("Failed to retrieve data: %v", err)
return nil, -1, err
}
return rows, 0, nil
}

(嗯,这似乎让缩进有点偏离)AsS 你可以看到我正在开始但没有关闭交易。这会导致 pg 端出现问题,其中每个选择都处于“事务中空闲”状态。

我已经尝试了 tx.Commit() 和 tx.Rollback() 并且在这两种情况下我都得到了错误:

"unknown response for simple query '3'"

"unknown response for simple query 'D'"

如何在 Go 中成功关闭交易?我希望更新我们的 pgbouncer.ini 以允许我为驱动程序库切换到 lib/pq,但我不确定这是否会直接帮助解决这个问题。

那么,我该如何正确关闭 tx 对象,或者有没有办法强制 Go 不在幕后使用准备好的语句?

谢谢弥敦道

我试着改变一下:

func TransactionQuery(db *sql.DB, baseQuery string) (rows *sql.Rows, code int, err error) {
tx, txErr := db.Begin()
if txErr != nil {
return nil, -1, txErr
}

/*selectStmt, prepErr := tx.Prepare(baseQuery)
if prepErr != nil {
return nil, -1, fmt.Errorf("Failed to prepare statment: %s Error: %v", baseQuery, prepErr)
}
*/
rows, err = tx.Query(baseQuery)
if err != nil {
fmt.Errorf("Failed to retrieve data: %v", err)
return nil, -1, err
}

/* if stmtErr := selectStmt.Close(); stmtErr != nil {
rows = nil
code = -2
err = fmt.Errorf("Failed to close statement: %v.", stmtErr)
}*/

if txCloseErr := tx.Commit(); txErr != nil {
rows = rows
code = -3
err = txCloseErr
}
return rows, 0, nil
}

我在日志中看到的这段代码:

pq: unexpected describe rows response: '3'

但是,我应该指出,这是第二次尝试使用 select 语句时。此应用程序选择一个批处理,对其进行处理,然后选择一个后续批处理。此错误发生在第二次选择时。第一次选择没有问题。

最佳答案

对于任何遇到这个问题的人,我已经解决了这个问题。

我的代码是将行对象返回给上面的调用代码(未显示)。在读取行之前关闭事务似乎是问题的原因。我不完全明白为什么,所以如果你这样做请澄清。

现在我返回行和事务对象。然后,当我读取所有行时,我回滚事务。这使一切正常。

谢谢弥敦道

关于postgresql - Golang - pgbouncer 和事务使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23010716/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com