@@ -158,8 +158,24 @@ void returnPooledConnection(PooledConnection c, boolean forceClose) {
158
158
}
159
159
}
160
160
161
- private PooledConnection extractFromFreeList (Object affinitiyId ) {
161
+ /**
162
+ * Tries to extract the best matching connection from the freeList.
163
+ * If there is none, it tries to create one or steal one from other affinity slot.
164
+ */
165
+ private PooledConnection extractFromFreeList (Object affinitiyId , boolean create ) throws SQLException {
166
+ PooledConnection c = extractFromFreeList (affinitiyId );
167
+ if (c == null && create ) {
168
+ c = createConnection ();
169
+ }
170
+ if (c == null && buffer .isAffinitySupported ()) {
171
+ // TODO: This "stealing" stragegy could be optimized.
172
+ // we might build a heurestic, which one would be the best candidate
173
+ c = extractFromFreeList (ConnectionBuffer .GET_LAST );
174
+ }
175
+ return c ;
176
+ }
162
177
178
+ private PooledConnection extractFromFreeList (Object affinitiyId ) {
163
179
PooledConnection c = buffer .removeFree (affinitiyId );
164
180
if (c == null ) {
165
181
return null ;
@@ -182,6 +198,21 @@ private boolean staleEviction(PooledConnection c) {
182
198
return pool .invalidConnection (c );
183
199
}
184
200
201
+
202
+ private PooledConnection createConnection () throws SQLException {
203
+ if (totalConnections () < maxSize ) {
204
+ // grow the connection pool
205
+ PooledConnection c = pool .createConnectionForQueue (connectionId ++);
206
+ int busySize = registerBusyConnection (c );
207
+ if (Log .isLoggable (DEBUG )) {
208
+ Log .debug ("DataSource [{0}] grow; id[{1}] busy[{2}] max[{3}]" , name , c .name (), busySize , maxSize );
209
+ }
210
+ return c ;
211
+ } else {
212
+ return null ;
213
+ }
214
+ }
215
+
185
216
private boolean stale (PooledConnection c ) {
186
217
return c .lastUsedTime () < System .currentTimeMillis () - validateStaleMillis ;
187
218
}
@@ -225,13 +256,9 @@ private PooledConnection _obtainConnection(Object affinitiyId) throws Interrupte
225
256
hitCount ++;
226
257
// are other threads already waiting? (they get priority)
227
258
if (waitingThreads == 0 ) {
228
- PooledConnection connection = extractFromFreeList (affinitiyId );
229
- if (connection != null ) {
230
- return connection ;
231
- }
232
- connection = createConnection ();
233
- if (connection != null ) {
234
- return connection ;
259
+ PooledConnection c = this .extractFromFreeList (affinitiyId , true );
260
+ if (c != null ) {
261
+ return c ;
235
262
}
236
263
}
237
264
try {
@@ -251,20 +278,6 @@ private PooledConnection _obtainConnection(Object affinitiyId) throws Interrupte
251
278
}
252
279
}
253
280
254
- private PooledConnection createConnection () throws SQLException {
255
- if (totalConnections () < maxSize ) {
256
- // grow the connection pool
257
- PooledConnection c = pool .createConnectionForQueue (connectionId ++);
258
- int busySize = registerBusyConnection (c );
259
- if (Log .isLoggable (DEBUG )) {
260
- Log .debug ("DataSource [{0}] grow; id[{1}] busy[{2}] max[{3}]" , name , c .name (), busySize , maxSize );
261
- }
262
- return c ;
263
- } else {
264
- return null ;
265
- }
266
- }
267
-
268
281
/**
269
282
* Got into a loop waiting for connections to be returned to the pool.
270
283
*/
@@ -277,13 +290,6 @@ private PooledConnection _obtainConnectionWaitLoop(Object affinitiyId) throws SQ
277
290
if (conn != null ) {
278
291
return conn ;
279
292
}
280
- // we could not create new connection, so we take the last one and change the affinity id
281
- if (buffer .isAffinitySupported ()) {
282
- conn = extractFromFreeList (ConnectionBuffer .GET_LAST );
283
- }
284
- if (conn != null ) {
285
- return conn ;
286
- }
287
293
String msg = "Unsuccessfully waited [" + waitTimeoutMillis + "] millis for a connection to be returned."
288
294
+ " No connections are free. You need to Increase the max connections of [" + maxSize + "]"
289
295
+ " or look for a connection pool leak using datasource.xxx.capturestacktrace=true" ;
@@ -296,8 +302,7 @@ private PooledConnection _obtainConnectionWaitLoop(Object affinitiyId) throws SQ
296
302
297
303
try {
298
304
nanos = notEmpty .awaitNanos (nanos );
299
- PooledConnection c = extractFromFreeList (affinitiyId );
300
-
305
+ PooledConnection c = this .extractFromFreeList (affinitiyId , false );
301
306
if (c != null ) {
302
307
// successfully waited
303
308
return c ;
0 commit comments