Domanda

Dettaglio tecnico

    .
  • go versione 1.2
  • Biblioteca POSTRGRES per GO BMILANY / PQ

Questo problema mi sta facendo impazzire e spero che qualcuno sarà in grado di aiutare.

Ho sviluppato un'applicazione in Gollang per leggere i dati da un database di PostGres e per ogni record effettua una richiesta HTTP e quindi aggiornare il database.

Questo è tutto abbastanza semplice. Tuttavia, abbiamo un pgbouncer in posizione. La configurazione che abbiamo per PGBouncer è tale da non supportare dichiarazioni preparate. Vai silenziosamente avvolge tutte le query in una dichiarazione preparata. Il modo in cui ciò per questo per pgbouncer è quello di impostare una transazione. Questo è tutto bene e buono per cose come inserto / aggiornamento / eliminazione.

Nel caso dell'istruzione Seleziona lo sto avvolgendo in transazione:

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, che sembra aver lanciato un po 'il rientrante) ASS CHE PUOI PUOI VEDERE I AZIONAMENTO BNUT NON CHIUSURA LA TRANSAZIONE. Ciò causa un problema nel lato PG delle cose in cui ogni selezione viene lasciata in uno stato "inattivo in transazione".

Ho provato tx.commit () e tx.rollback () e in entrambi i casi ottengo errori:

"unknown response for simple query '3'"
.

o

"unknown response for simple query 'D'"
.

Ho Fermi con successo la transazione in movimento? Sperando di ottenere il nostro PGBouncer.ini aggiornato per consentirmi di passare a Lib / PQ per la libreria dei conducenti, ma non sono sicuro se ciò aiuterà direttamente questo problema.

Allora, come chiudere correttamente l'oggetto TX o c'è un modo per forzare andare a non usare dichiarazioni preparate sotto il cofano?

Grazie Nathan

Ho provato a cambiare un po ':

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
}
.

Cosa vedo nei registri con questo codice:

pq: unexpected describe rows response: '3'
.

Tuttavia, dovrei sottolineare che questo è quando si prova una dichiarazione di selezione per la seconda volta. Questa applicazione seleziona un batch, si occupa di esso e quindi seleziona un batch successivo. Questo errore avviene sul secondo select. Non ci sono problemi con la prima selezione.

È stato utile?

Soluzione

Per chiunque altro che colpisce questo ho risolto questo.

Il codice che avevo restituito l'oggetto delle righe al codice di chiamata (non mostrato) sopra.Chiudere la transazione prima che le righe siano state lette sembravano essere la causa del problema.Non capisco perfettamente perché si prega di chiarire se lo fai.

Ora restituisco sia le righe che l'oggetto transazione.Poi quando ho letto tutte le righe che rollback la transazione.Questo continua a lavorare.

Grazie Nathan

Altri suggerimenti

tx.query restituisce un'istanza di sql.rows, che è un cursore del set di risultati.I dati non sono stati necessariamente recuperati mentre si sta interando questo cursore.La transazione deve rimanere aperta mentre si sta interando il cursore.

Questo è il motivo per cui non è più possibile iterare il cursore una volta chiusa la transazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top