Golang - dcmtk-www e o uso de transações
-
21-12-2019 - |
Pergunta
Tecnologia Detalhes
- acesse a versão 1.2
- postrgres biblioteca para ir bmizerany/pq
Esse problema está me deixando louco e eu estou esperando que alguém vai ser capaz de ajudar.
Eu desenvolvi um aplicativo em golang para ler dados de um banco de dados postgres e para cada registro de fazer uma solicitação http e, em seguida, atualizar o banco de dados.
Tudo isso é bastante simples.No entanto, temos dcmtk-www no lugar.A configuração que tem para dcmtk-www é tal que ele não oferece suporte a instruções preparadas.Ir silenciosamente envolve todas as consultas em uma declaração preparada.A maneira de contornar isso para dcmtk-www é definir uma transação.Que é tudo muito bem para coisas como inserir/atualizar/excluir.
No caso da instrução select estou envolvido na transação:
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 ter lançar o recuo fora de um pouco) Bunda, você pode ver que eu estou começando bnut não fechamento da transação.Isso causa um problema na pg lado das coisas, onde cada escolha é deixada em um "ocioso na transação" do estado.
Eu tentei tx.Commit() e tx.Rollback() e, em ambos os casos, eu recebo erros:
"unknown response for simple query '3'"
ou
"unknown response for simple query 'D'"
Ho me com êxito fechar a transação no Ir?Eu estou esperando para receber a nossa dcmtk-www.ini atualizado para permitir-me a mudar para lib/pq para a biblioteca de driver, mas eu não tenho certeza se isso vai ajudar diretamente a esta questão.
Então, como faço para fechar o tx objeto corretamente ou há uma maneira de forçar a Ir para não usar instruções preparadas sob o capô?
Obrigado Nathan
Eu tentei mudar um pouco as coisas:
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
}
O que eu vejo nos logs com este código:
pq: unexpected describe rows response: '3'
No entanto, gostaria de salientar que este é o momento de tentar uma instrução select para o segundo tempo.Este aplicativo seleciona um lote, lida com ele e, em seguida, seleciona um em lotes subseqüentes.Este erro acontece na segunda escolha.Não há problemas com a primeira escolha.
Solução
Para qualquer pessoa que atinge esse eu ter resolvido isso.
O código que eu tinha era de retornar as linhas de objeto para o código de chamada (não mostrado) acima.O fechamento da transação, antes que as linhas foram lidas parecia ser a causa do problema.Eu não entendemos por que então, por favor, esclarecer se o fizer.
Agora eu retorno as linhas e o objeto de transação.Então, quando eu ler todas as linhas de eu reverter a transação.isso mantém tudo funcionando.
Obrigado Nathan
Outras dicas
Tx.Consulta retorna uma instância de sql.Linhas, que é um cursor para definir o resultado.Os dados não necessariamente foram recuperados enquanto você está iterando este cursor.A transação deve permanecer aberta enquanto você está iterando o cursor.
É por isso que você não poderia mais iterar o cursor uma vez que a transação foi fechada.