mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
database/sql: close driver Stmt before releasing Conn
From the issue, which describes it as well as I could: database/sql assumes that driver.Stmt.Close does not need the connection. see database/sql/sql.go:1308: This puts the Rows' connection back into the idle pool, and then calls the driver.Stmt.Close method of the Stmt it belongs to. In the postgresql driver implementation (https://github.com/lib/pq), Stmt.Close communicates with the server (on the connection that was just put back into the idle pool). Most of the time, this causes no problems, but if another goroutine makes a query at the right (wrong?) time, chaos results. In any case, traffic is being sent on "free" connections shortly after they are freed, leading to race conditions that kill the driver code. Fixes #5283 R=golang-dev, r CC=golang-dev https://golang.org/cl/8633044
This commit is contained in:
parent
80de7ab190
commit
36d3bef8a3
3 changed files with 39 additions and 1 deletions
|
|
@ -854,6 +854,26 @@ func TestCloseConnBeforeStmts(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// golang.org/issue/5283: don't release the Rows' connection in Close
|
||||
// before calling Stmt.Close.
|
||||
func TestRowsCloseOrder(t *testing.T) {
|
||||
db := newTestDB(t, "people")
|
||||
defer closeDB(t, db)
|
||||
|
||||
db.SetMaxIdleConns(0)
|
||||
setStrictFakeConnClose(t)
|
||||
defer setStrictFakeConnClose(nil)
|
||||
|
||||
rows, err := db.Query("SELECT|people|age,name|")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = rows.Close()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func manyConcurrentQueries(t testOrBench) {
|
||||
maxProcs, numReqs := 16, 500
|
||||
if testing.Short() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue