mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
database/sql: Retry with a fresh connection after maxBadConnRetries
Previously if the connection pool was larger than maxBadConnRetries and there were a lot of bad connections in the pool (for example if the database server was restarted), a query might have failed with an ErrBadConn unnecessarily. Instead of trying to guess how many times to retry, try maxBadConnRetries times and then force a fresh connection to be used for the last attempt. At the same time, lower maxBadConnRetries to a smaller value now that it's not that important to retry so many times from the free connection list. Fixes #8834 Change-Id: I6542f151a766a658980fb396fa4880ecf5874e3d Reviewed-on: https://go-review.googlesource.com/2034 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
d5ef698142
commit
c468f94672
3 changed files with 147 additions and 42 deletions
|
|
@ -89,7 +89,10 @@ type fakeConn struct {
|
|||
stmtsMade int
|
||||
stmtsClosed int
|
||||
numPrepare int
|
||||
bad bool
|
||||
|
||||
// bad connection tests; see isBad()
|
||||
bad bool
|
||||
stickyBad bool
|
||||
}
|
||||
|
||||
func (c *fakeConn) incrStat(v *int) {
|
||||
|
|
@ -243,13 +246,15 @@ func (db *fakeDB) columnType(table, column string) (typ string, ok bool) {
|
|||
}
|
||||
|
||||
func (c *fakeConn) isBad() bool {
|
||||
// if not simulating bad conn, do nothing
|
||||
if !c.bad {
|
||||
if c.stickyBad {
|
||||
return true
|
||||
} else if c.bad {
|
||||
// alternate between bad conn and not bad conn
|
||||
c.db.badConn = !c.db.badConn
|
||||
return c.db.badConn
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
// alternate between bad conn and not bad conn
|
||||
c.db.badConn = !c.db.badConn
|
||||
return c.db.badConn
|
||||
}
|
||||
|
||||
func (c *fakeConn) Begin() (driver.Tx, error) {
|
||||
|
|
@ -466,7 +471,7 @@ func (c *fakeConn) Prepare(query string) (driver.Stmt, error) {
|
|||
panic("nil c.db; conn = " + fmt.Sprintf("%#v", c))
|
||||
}
|
||||
|
||||
if hookPrepareBadConn != nil && hookPrepareBadConn() {
|
||||
if c.stickyBad || (hookPrepareBadConn != nil && hookPrepareBadConn()) {
|
||||
return nil, driver.ErrBadConn
|
||||
}
|
||||
|
||||
|
|
@ -529,7 +534,7 @@ func (s *fakeStmt) Exec(args []driver.Value) (driver.Result, error) {
|
|||
return nil, errClosed
|
||||
}
|
||||
|
||||
if hookExecBadConn != nil && hookExecBadConn() {
|
||||
if s.c.stickyBad || (hookExecBadConn != nil && hookExecBadConn()) {
|
||||
return nil, driver.ErrBadConn
|
||||
}
|
||||
|
||||
|
|
@ -613,7 +618,7 @@ func (s *fakeStmt) Query(args []driver.Value) (driver.Rows, error) {
|
|||
return nil, errClosed
|
||||
}
|
||||
|
||||
if hookQueryBadConn != nil && hookQueryBadConn() {
|
||||
if s.c.stickyBad || (hookQueryBadConn != nil && hookQueryBadConn()) {
|
||||
return nil, driver.ErrBadConn
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue