database/sql: Conn.Raw() will not close the connection on error unless f() returns driver.ErrBadConn #47500
Labels
FrozenDueToAge
NeedsInvestigation
Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
In the following handler, where
*Server
hasdb *sql.DB
:(yes I am aware
PingContext()
exists)What did you expect to see?
When
f()
used in the call toRaw()
fails, I expected the connection to be closed, as happens with othersql.Conn
methods.What did you see instead?
When the ping fails, the bad connection is not closed. It is then ultimately returned to the connection pool after
sql.Conn.Close()
is called.In my use case this leads to the handler repeatedly failing and then things like kubernetes liveness probe failures and service restarts.
Analysis
The
Raw()
function will only close the connection if the error returned byf()
is (==
)driver.ErrBadConn
https://cs.opensource.google/go/go/+/refs/tags/go1.16.6:src/database/sql/sql.go;drc=422dc83baa2816ca1d9a0aa3f1aaf4c47c8098ad;l=1979.I think this behaviour should be documented. Currently "Once f returns and err is nil, the Conn will continue to be usable until Conn.Close is called." is inaccurate. Perhaps "Once f returns and err is not equal to driver.ErrBadConn, the Conn will continue to be usable until Conn.Close is called." would be more precise?
It might also be worth changing the behaviour so that either any non-nil error, or any error which wraps
driver.ErrBadConn
will close the connection, the current behaviour surprised me.The text was updated successfully, but these errors were encountered: