技术细节

  • go版本1.2
  • Postrgres Go BMizerany / PQ

这个问题让我发疯了,我希望有人能够提供帮助。

我已经开发在golang应用程序读取从Postgres数据库和每个记录数据使一个HTTP请求,然后更新该数据库。

这一切都足够简单。但是,我们有PGBouncer到位。我们为PGBouncer的配置是这样它不支持准备的陈述。围棋默默包裹在一份声明中的所有查询。围绕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
    }
.

(HHMM,似乎有抛缩进取下一小) ass你可以看到我开始bnut未关闭交易。这会导致在事物的PG侧,每一个选择是在事务”状态的“怠速留下了问题。

我已经尝试了tx.commit()和tx.rollback()和在两种情况下我得到错误:

"unknown response for simple query '3'"
.

"unknown response for simple query 'D'"
.

何我成功地关闭围棋交易?我希望能够让我们的pgbouncer.ini更新,允许我为驱动程序库切换到lib / pq,但我不确定这是否会直接帮助这个问题。

所以,如何正确关闭TX对象,或者有没有办法强制转到不使用引擎盖下的准备语句?

谢谢 内森

我试图改变一下:

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语句的时候。此应用程序选择批处理,处理它,然后选择后续批处理。第二个选择时会发生此错误。第一个选择没有问题。

有帮助吗?

解决方案

对于其他人击中这个,我已经解决了这一点。

我已经将行对象返回到上面的呼叫代码(未示出)。在读取行之前结束交易似乎是问题的原因。我完全明白为什么如此,请澄清你是否这样做。

现在我返回行和事务对象。然后,当我读取所有行时,我回滚事务。这让一切都能工作。

谢谢 内森

其他提示

tx.query返回sql.rows的实例,它是一个光标到结果集。在迭代此光标时,数据并不一定检索。在迭代光标时,事务必须保持打开。

这就是为什么在交易关闭后,您无法再迭代光标。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top