@@ -83,7 +83,7 @@ type Pool struct {
8383 config * Config
8484 beforeConnect func (context.Context , * pgx.ConnConfig ) error
8585 afterConnect func (context.Context , * pgx.Conn ) error
86- beforeAcquire func (context.Context , * pgx.Conn ) bool
86+ prepareConn func (context.Context , * pgx.Conn ) ( bool , error )
8787 afterRelease func (* pgx.Conn ) bool
8888 beforeClose func (* pgx.Conn )
8989 minConns int32
@@ -118,8 +118,22 @@ type Config struct {
118118 // BeforeAcquire is called before a connection is acquired from the pool. It must return true to allow the
119119 // acquisition or false to indicate that the connection should be destroyed and a different connection should be
120120 // acquired.
121+ //
122+ // Deprecated: Use PrepareConn instead. If both PrepareConn and BeforeAcquire are set, PrepareConn will take
123+ // precedence, ignoring BeforeAcquire.
121124 BeforeAcquire func (context.Context , * pgx.Conn ) bool
122125
126+ // PrepareConn is called before a connection is acquired from the pool. If this function returns true, the connection
127+ // is considered valid. If the function returns a non-nil error, the instigating query will fail with the returned error.
128+ //
129+ // Specifically, this means that:
130+ //
131+ // - It must return true and a nil error to allow acquisition and the query to proceed.
132+ // - If it returns true and an error, the connection will be returned to the pool, and the instigating query will fail with the returned error.
133+ // - If it returns false, and an error, the query will fail with the returned error, and the connection will be destroyed.
134+ // - If it returns false and a nil error, the connection will be returned to the pool, and the instigating query will be retried on a new connection.
135+ PrepareConn func (context.Context , * pgx.Conn ) (bool , error )
136+
123137 // AfterRelease is called after a connection is released, but before it is returned to the pool. It must return true to
124138 // return the connection to the pool or false to destroy the connection.
125139 AfterRelease func (* pgx.Conn ) bool
@@ -189,11 +203,18 @@ func NewWithConfig(ctx context.Context, config *Config) (*Pool, error) {
189203 panic ("config must be created by ParseConfig" )
190204 }
191205
206+ prepareConn := config .PrepareConn
207+ if prepareConn == nil && config .BeforeAcquire != nil {
208+ prepareConn = func (ctx context.Context , conn * pgx.Conn ) (bool , error ) {
209+ return config .BeforeAcquire (ctx , conn ), nil
210+ }
211+ }
212+
192213 p := & Pool {
193214 config : config ,
194215 beforeConnect : config .BeforeConnect ,
195216 afterConnect : config .AfterConnect ,
196- beforeAcquire : config . BeforeAcquire ,
217+ prepareConn : prepareConn ,
197218 afterRelease : config .AfterRelease ,
198219 beforeClose : config .BeforeClose ,
199220 minConns : config .MinConns ,
@@ -560,11 +581,23 @@ func (p *Pool) Acquire(ctx context.Context) (c *Conn, err error) {
560581 }
561582 }
562583
563- if p .beforeAcquire == nil || p .beforeAcquire (ctx , cr .conn ) {
564- return cr .getConn (p , res ), nil
584+ if p .prepareConn != nil {
585+ ok , err := p .prepareConn (ctx , cr .conn )
586+ if ! ok {
587+ res .Destroy ()
588+ }
589+ if err != nil {
590+ if ok {
591+ res .Release ()
592+ }
593+ return nil , err
594+ }
595+ if ! ok {
596+ continue
597+ }
565598 }
566599
567- res . Destroy ()
600+ return cr . getConn ( p , res ), nil
568601 }
569602}
570603
@@ -588,11 +621,14 @@ func (p *Pool) AcquireAllIdle(ctx context.Context) []*Conn {
588621 conns := make ([]* Conn , 0 , len (resources ))
589622 for _ , res := range resources {
590623 cr := res .Value ()
591- if p .beforeAcquire == nil || p .beforeAcquire (ctx , cr .conn ) {
592- conns = append (conns , cr .getConn (p , res ))
593- } else {
594- res .Destroy ()
624+ if p .prepareConn != nil {
625+ ok , err := p .prepareConn (ctx , cr .conn )
626+ if ! ok || err != nil {
627+ res .Destroy ()
628+ continue
629+ }
595630 }
631+ conns = append (conns , cr .getConn (p , res ))
596632 }
597633
598634 return conns
0 commit comments