diff --git a/CHANGELOG.md b/CHANGELOG.md index a4fdaf92..35b24b5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ Technically, two changes are breaking changes, but in practice these are extreme * Conn.Begin and Conn.BeginTx return a Tx interface instead of the internal dbTx struct. This is necessary for the Conn.Begin method to signature as other methods that begin a transaction. * Add Conn() to Tx interface. This is necessary to allow code using a Tx to access the *Conn (and pgconn.PgConn) on which the Tx is executing. +## Fixes + +* Releasing a busy connection closes the connection instead of returning an unusable connection to the pool + # 4.0.1 (September 19, 2019) * Fix statement cache cleanup. diff --git a/go.mod b/go.mod index 6e012e54..7d93e082 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.12 require ( github.com/cockroachdb/apd v1.1.0 github.com/gofrs/uuid v3.2.0+incompatible - github.com/jackc/pgconn v1.0.1 + github.com/jackc/pgconn v1.1.0 github.com/jackc/pgio v1.0.0 github.com/jackc/pgproto3/v2 v2.0.0 github.com/jackc/pgtype v1.0.1 diff --git a/go.sum b/go.sum index ff0e5499..0f20b219 100644 --- a/go.sum +++ b/go.sum @@ -28,6 +28,8 @@ github.com/jackc/pgconn v1.0.0 h1:HFtb+O3S+OgYs56mcFuFHiUStvABkdUrS+UrPgKqfMs= github.com/jackc/pgconn v1.0.0/go.mod h1:GgY/Lbj1VonNaVdNUHs9AwWom3yP2eymFQ1C8z9r/Lk= github.com/jackc/pgconn v1.0.1 h1:ZANo4pIkeHKIVD1cQMcxu8fwrwIICLblzi9HCjooZeQ= github.com/jackc/pgconn v1.0.1/go.mod h1:GgY/Lbj1VonNaVdNUHs9AwWom3yP2eymFQ1C8z9r/Lk= +github.com/jackc/pgconn v1.1.0 h1:10i6DMVJOSko/sD3FLpFKBHONzDGKkX8pbLyHC8B92o= +github.com/jackc/pgconn v1.1.0/go.mod h1:GgY/Lbj1VonNaVdNUHs9AwWom3yP2eymFQ1C8z9r/Lk= github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= diff --git a/pgxpool/conn.go b/pgxpool/conn.go index 315eb09d..1172fbcb 100644 --- a/pgxpool/conn.go +++ b/pgxpool/conn.go @@ -27,7 +27,7 @@ func (c *Conn) Release() { c.res = nil now := time.Now() - if conn.IsClosed() || conn.PgConn().TxStatus() != 'I' || (now.Sub(res.CreationTime()) > c.p.maxConnLifetime) { + if conn.IsClosed() || conn.PgConn().IsBusy() || conn.PgConn().TxStatus() != 'I' || (now.Sub(res.CreationTime()) > c.p.maxConnLifetime) { res.Destroy() return } diff --git a/pgxpool/pool_test.go b/pgxpool/pool_test.go index d6640a71..8db8f169 100644 --- a/pgxpool/pool_test.go +++ b/pgxpool/pool_test.go @@ -210,6 +210,26 @@ func TestConnReleaseChecksMaxConnLifetime(t *testing.T) { assert.EqualValues(t, 0, stats.TotalConns()) } +func TestConnReleaseClosesBusyConn(t *testing.T) { + t.Parallel() + + db, err := pgxpool.Connect(context.Background(), os.Getenv("PGX_TEST_DATABASE")) + require.NoError(t, err) + defer db.Close() + + c, err := db.Acquire(context.Background()) + require.NoError(t, err) + + _, err = c.Query(context.Background(), "select generate_series(1,10)") + require.NoError(t, err) + + c.Release() + waitForReleaseToComplete() + + stats := db.Stat() + assert.EqualValues(t, 0, stats.TotalConns()) +} + func TestPoolBackgroundChecksMaxConnLifetime(t *testing.T) { t.Parallel()