Tech ParticolareGolang - pgbouncer e l'uso delle transazioni
- versione 1.2 go
- biblioteca postrgres per go bmizerany/pq
Questo problema mi sta facendo impazzire e spero che qualcuno sarà in grado di aiutare.
Ho sviluppato un'applicazione in golang per leggere i dati da un database postgres e per ogni record effettuare una richiesta http e quindi aggiornare il database.
Questo è tutto abbastanza semplice. Tuttavia, abbiamo pgbouncer sul posto. La configurazione che abbiamo per pgbouncer è tale che non supporta le istruzioni preparate. Vai silenziosamente a tutte le query in una dichiarazione preparata. Il modo per aggirare questo per pgbouncer è impostare una transazione. Questo va bene per cose come insert/update/delete.
Nel caso della dichiarazione prescelta che sto avvolgendolo 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 avere gettare il rientro fuori un po ') AsS potete vedere sto iniziando BNUT non di chiusura la transazione. Ciò causa un problema nel lato pg delle cose in cui ogni selezione viene lasciata in uno stato "inattivo nella 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 chiudo con successo l'operazione in Go? Spero di ottenere i nostri pgbouncer.ini aggiornati per permettere a me di passare a lib/pq per la libreria conducente ma io non sono sicuro che questo aiuterà direttamente questo problema.
Quindi, come posso chiudere correttamente l'oggetto tx o c'è un modo per forzare Vai a non usare istruzioni preparate sotto il cofano?
Grazie Nathan
ho cercato di cambiare le cose 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
}
Quello che vedo nei log con questo codice:
pq: unexpected describe rows response: '3'
Tuttavia, dovrei Fai notare che questo è quando provi una dichiarazione di selezione per la seconda volta. Questa applicazione seleziona un batch, lo gestisce e seleziona un batch successivo. Questo errore si verifica nella seconda selezione. Non ci sono problemi con la prima selezione.
C'è qualcosa nel registro Postgres? Qui possono essere registrate dichiarazioni problematiche che ti permetteranno di vedere se ciò che pensi venga inviato è effettivamente ricevuto dal db. –
Devo chiedere al team DBA per quello che non ho accesso a quei registri. È interessante notare che, se lascio la transazione inclusa, l'app viene eseguita come previsto, ma blocca il pgbouncer con lo stato di inattività nello stato della transazione. – nathj07