database/sql: ensure Rows is closed when Tx closes

Close any Rows queried within a Tx when the Tx is closed. This prevents
the Tx from blocking on rollback if a Rows query has not been closed yet.

Fixes #20575

Change-Id: I4efe9c4150e951d8a0f1c40d9d5e325964fdd608
Reviewed-on: https://go-review.googlesource.com/44812
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Daniel Theophanes 2017-06-05 09:04:05 -07:00
parent eea8c88a09
commit 729685c1d1
2 changed files with 56 additions and 13 deletions

View file

@ -2467,6 +2467,32 @@ func TestManyErrBadConn(t *testing.T) {
}
}
// TestIssue20575 ensures the Rows from query does not block
// closing a transaction. Ensure Rows is closed while closing a trasaction.
func TestIssue20575(t *testing.T) {
db := newTestDB(t, "people")
tx, err := db.Begin()
if err != nil {
t.Fatal(err)
}
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
_, err = tx.QueryContext(ctx, "SELECT|people|age,name|")
if err != nil {
t.Fatal(err)
}
// Do not close Rows from QueryContext.
err = tx.Rollback()
if err != nil {
t.Fatal(err)
}
select {
default:
case <-ctx.Done():
t.Fatal("timeout: failed to rollback query without closing rows:", ctx.Err())
}
}
// golang.org/issue/5718
func TestErrBadConnReconnect(t *testing.T) {
db := newTestDB(t, "foo")