@@ -310,11 +310,12 @@ private PooledConnection _obtainConnectionWaitLoop(Object affinitiyId) throws SQ
310310 }
311311
312312 PoolStatus shutdown (boolean closeBusyConnections ) {
313+
313314 lock .lock ();
314315 try {
315316 doingShutdown = true ;
316317 PoolStatus status = createStatus ();
317- closeFreeConnections ( true );
318+ doCloseFreeConnections ( buffer . clearFreeList (), true );
318319
319320 if (!closeBusyConnections ) {
320321 // connections close on return to pool
@@ -323,7 +324,7 @@ PoolStatus shutdown(boolean closeBusyConnections) {
323324 if (buffer .busySize () > 0 ) {
324325 Log .warn ("Closing busy connections on shutdown size: {0}" , buffer .busySize ());
325326 dumpBusyConnectionInformation ();
326- closeBusyConnections ( 0 );
327+ doCloseBusyConnections ( buffer . cleanupBusyList ( 0 ), true );
327328 }
328329 }
329330 return status ;
@@ -339,24 +340,28 @@ PoolStatus shutdown(boolean closeBusyConnections) {
339340 * <p>
340341 * This is typically done when a database down event occurs.
341342 */
342- void reset (long leakTimeMinutes ) {
343+ void reset (long leakTimeMinutes , boolean logErrors ) {
344+ List <PooledConnection > busyConnections ;
345+ List <PooledConnection > freeConnections ;
343346 lock .lock ();
344347 try {
345348 PoolStatus status = createStatus ();
346349 Log .info ("Resetting DataSource [{0}] {1}" , name , status );
347350 lastResetTime = System .currentTimeMillis ();
348351
349- closeFreeConnections (false );
350- closeBusyConnections (leakTimeMinutes );
351-
352- String busyInfo = getBusyConnectionInformation ();
353- if (!busyInfo .isEmpty ()) {
354- Log .info ("Busy Connections:\n {0}" , busyInfo );
355- }
352+ freeConnections = buffer .clearFreeList ();
353+ busyConnections = buffer .cleanupBusyList (leakTimeMinutes );
356354
357355 } finally {
358356 lock .unlock ();
359357 }
358+ // we are closing the connections outside the lock
359+ doCloseFreeConnections (freeConnections , logErrors );
360+ doCloseBusyConnections (busyConnections , logErrors );
361+ String busyInfo = getBusyConnectionInformation ();
362+ if (!busyInfo .isEmpty ()) {
363+ Log .info ("Busy Connections:\n {0}" , busyInfo );
364+ }
360365 }
361366
362367 void trim (long maxInactiveMillis , long maxAgeMillis ) {
@@ -401,48 +406,42 @@ private boolean trimInactiveConnections(long maxInactiveMillis, long maxAgeMilli
401406 }
402407
403408 /**
404- * Close all the connections that are in the free list.
409+ * Close all the connections that are from the free list.
405410 */
406- private void closeFreeConnections (boolean logErrors ) {
407- List <PooledConnection > tempList ;
408- lock .lock ();
409- try {
410- tempList = buffer .clearFreeList ();
411- } finally {
412- lock .unlock ();
413- }
414- // closing the connections is done outside lock
411+ void doCloseFreeConnections (List <PooledConnection > connections , boolean logErrors ) {
415412 if (Log .isLoggable (System .Logger .Level .TRACE )) {
416- Log .trace ("... closing all {0} connections from the free list with logErrors: {1}" , tempList .size (), logErrors );
413+ Log .trace ("... closing all {0} connections from the free list with logErrors: {1}" , connections .size (), logErrors );
417414 }
418- for (PooledConnection connection : tempList ) {
419- connection .closeConnectionFully (logErrors );
415+ for (PooledConnection pc : connections ) {
416+ try {
417+ pc .closeConnectionFully (logErrors );
418+ } catch (Throwable ex ) {
419+ Log .error ("Error when closing potentially leaked connection " + pc .description (), ex );
420+ }
420421 }
421422 }
422423
423424 /**
424425 * Close any busy connections that have not been used for some time.
425426 * <p>
427+ * The connections are removed with buffer.cleanupBusyList(leakTimeout)
428+ * from the buffer and are normally closed outside the lock.
426429 * These connections are considered to have leaked from the connection pool.
427430 * <p>
428431 * Connection leaks occur when code doesn't ensure that connections are
429432 * closed() after they have been finished with. There should be an
430433 * appropriate try catch finally block to ensure connections are always
431434 * closed and put back into the pool.
432435 */
433- void closeBusyConnections (long leakTimeMinutes ) {
434- List <PooledConnection > tempList ;
435- lock .lock ();
436- try {
437- tempList = buffer .cleanupBusyList (leakTimeMinutes );
438- } finally {
439- lock .unlock ();
436+ void doCloseBusyConnections (List <PooledConnection > connections , boolean logErrors ) {
437+ if (Log .isLoggable (System .Logger .Level .TRACE )) {
438+ Log .trace ("... closing all {0} connections from the busy list with logErrors: {1}" , connections .size (), logErrors );
440439 }
441- for (PooledConnection pc : tempList ) {
440+ for (PooledConnection pc : connections ) {
442441 try {
443442 Log .warn ("DataSource closing busy connection? {0}" , pc .fullDescription ());
444443 System .out .println ("CLOSING busy connection: " + pc .fullDescription ());
445- pc .closeConnectionFully (false );
444+ pc .closeConnectionFully (logErrors );
446445 } catch (Exception ex ) {
447446 Log .error ("Error when closing potentially leaked connection " + pc .description (), ex );
448447 }
0 commit comments