Pregunta

Detalle de tecnología

  • go versión 1.2
  • Biblioteca POSTRGRES PARA IR BMIZERANY / PQ

Este problema me está volviendo loco y espero que alguien pueda ayudar.

He desarrollado una aplicación en Golang para leer datos de una base de datos de Postgres y para cada registro Hacer una solicitud HTTP y luego actualizar la base de datos.

Todo esto es lo suficientemente simple. Sin embargo, tenemos PGBOUNCER en su lugar. La configuración que tenemos para PGBOUNCER es tal que no admite las declaraciones preparadas. Ve en silencio, envuelve todas las consultas en una declaración preparada. El camino alrededor de esto para PGBOUNCER es configurar una transacción. Eso es todo bien y bueno para cosas como insertar / actualizar / eliminar.

En el caso de la instrucción SELECT, lo estoy envolviendo en la transacción:

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, que parece haber lanzado un poco de indentación de un poco) Culo que puedes ver, estoy empezando, no estoy cerrando la transacción. Esto provoca un problema en el lado PG de las cosas donde cada selecto se deja en un estado 'inactivo en transacción ".

He intentado tx.commit () y tx.rollback () y en ambos casos obtengo errores:

"unknown response for simple query '3'"

o

"unknown response for simple query 'D'"

HO ¿Cierro con éxito la transacción en Go? Espero obtener nuestro PgBounter.ini actualizado para permitirme cambiar a lib / pq para la biblioteca del controlador, pero no estoy seguro de si eso ayudará directamente a este problema.

Entonces, ¿cómo cierro el objeto TX correctamente o si hay una manera de forzar, ir a no usar declaraciones preparadas debajo del capó?

gracias NATHAN

He intentado cambiar las cosas un poco:

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
}

Qué veo en los registros con este código:

pq: unexpected describe rows response: '3'

Sin embargo, debería señalar que esto es cuando intenta una declaración de selección por segunda vez. Esta aplicación selecciona un lote, se ocupa de él y luego selecciona un lote posterior. Este error ocurre en la segunda selección. No hay problemas con el primer selecto.

¿Fue útil?

Solución

Para cualquier otra persona que golpea esto, he resuelto esto.

El código que tuvo estaba devolviendo el objeto de las filas al código de llamada (no se muestra) arriba.Cerrando la transacción antes de que se lea las filas parecía ser la causa del problema.No entiendo completamente por qué, por favor, aclare si lo hace.

Ahora devuelvo las filas y el objeto de transacción.Luego, cuando he leído todas las filas, retrocede la transacción.Esto mantiene todo funcionando.

gracias NATHAN

Otros consejos

tx.Query devuelve una instancia de SQL.ROWS, que es un cursor al conjunto de resultados.Los datos no se han recuperado necesariamente mientras está iterando este cursor.La transacción debe permanecer abierta mientras está iterando el cursor.

Por eso ya no podía iterar al cursor una vez que se cerró la transacción.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top