database/sql: Avoid re-preparing statements when all connections are busy

Previously, if all connections were busy, we would always
re-prepare the statement on the connection we were assigned from
the pool.  That meant that if all connections were busy most of the
time, the number of prepared statements for each connection would
keep increasing over time.

Instead, after getting a free connection, check to see if the
statement has already been prepared on it, and reuse the statement
handle if so.

LGTM=bradfitz
R=golang-codereviews, gobot, bradfitz
CC=golang-codereviews
https://golang.org/cl/116930043
This commit is contained in:
Marko Tiikkaja 2014-09-02 09:08:41 -07:00 committed by Brad Fitzpatrick
parent 60447c2d95
commit 90e2e2b896
2 changed files with 42 additions and 31 deletions

View file

@ -1348,6 +1348,11 @@ func TestErrBadConnReconnect(t *testing.T) {
return nil
})
// Provide a way to force a re-prepare of a statement on next execution
forcePrepare := func(stmt *Stmt) {
stmt.css = nil
}
// stmt.Exec
stmt1, err := db.Prepare("INSERT|t1|name=?,age=?,dead=?")
if err != nil {
@ -1355,9 +1360,7 @@ func TestErrBadConnReconnect(t *testing.T) {
}
defer stmt1.Close()
// make sure we must prepare the stmt first
for _, cs := range stmt1.css {
cs.dc.inUse = true
}
forcePrepare(stmt1)
stmtExec := func() error {
_, err := stmt1.Exec("Gopher", 3, false)
@ -1373,9 +1376,7 @@ func TestErrBadConnReconnect(t *testing.T) {
}
defer stmt2.Close()
// make sure we must prepare the stmt first
for _, cs := range stmt2.css {
cs.dc.inUse = true
}
forcePrepare(stmt2)
stmtQuery := func() error {
rows, err := stmt2.Query()