lib / pq

Pure Go Postgres driver for database/sql
https://pkg.go.dev/github.com/lib/pq
MIT License
9.02k stars 910 forks source link

Context cancellation during a Transaction can result in spurious sql.ErrNoRows #874

Open tim2bolbrock opened 5 years ago

tim2bolbrock commented 5 years ago
tx, err = db.BeginTx(ctx, nil)
err = tx.QueryRowContext(ctx, query).Scan(&result)

When the query is cancelled by the expiration of ctx, err can sometimes be a spurious sql.ErrNoRows instead of the appropriate "context deadline exceeded" or "pq: canceling statement due to user request". This does not seem to happen if querying without a transaction.

This looks to be related to a since-fixed panic with similar triggers. I modified blinsay's reproduction to test with and without a transaction and to try a simple workaround of double checking the context in case of sql.ErrNoRows. Run a local Postgres instance, go run pq_ctx_repro.go -tx=0/1 &>output.log, run for a minute or two, then grep -E -o "error=.*" <output.log | sort | uniq -c to tally up the errors received.

-tx=0

   1 error="context deadline exceeded"
4067 error="pq: canceling statement due to user request"

-tx=1

   5 error="context deadline exceeded"
3164 error="pq: canceling statement due to user request"
  21 error="sql: no rows in result set"

Versions tested:

pq driver 1.1.0 Postgres 11.2 go 1.12.5