1 2 3 if (breakAfterAcquireFailure) { break ; }
1 2 3 if (physicalConnection == null ) { continue ; }
原因 breakAfterAcquireFailur
默认为false
。
且配置文件或代码中未设置 breakAfterAcquireFailur
属性和maxWait
属性,
且因为循环为for(;;)
,从而导致死循环重试。
解决 在配置文件或代码中设置 breakAfterAcquireFailur
属性和maxWait
属性即可。
完整源码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 public class CreateConnectionThread extends Thread { public CreateConnectionThread (String name) { super (name); this .setDaemon(true ); } public void run () { initedLatch.countDown(); long lastDiscardCount = 0 ; int errorCount = 0 ; for (;;) { try { lock.lockInterruptibly(); } catch (InterruptedException e2) { break ; } long discardCount = DruidDataSource.this .discardCount; boolean discardChanged = discardCount - lastDiscardCount > 0 ; lastDiscardCount = discardCount; try { boolean emptyWait = true ; if (createError != null && poolingCount == 0 && !discardChanged) { emptyWait = false ; } if (emptyWait && asyncInit && createCount < initialSize) { emptyWait = false ; } if (emptyWait) { if (poolingCount >= notEmptyWaitThreadCount && (!(keepAlive && activeCount + poolingCount < minIdle)) && !isFailContinuous() ) { empty.await(); } if (activeCount + poolingCount >= maxActive) { empty.await(); continue ; } } } catch (InterruptedException e) { lastCreateError = e; lastErrorTimeMillis = System.currentTimeMillis(); if (!closing) { LOG.error ("create connection Thread Interrupted, url: " + jdbcUrl, e); } break ; } finally { lock.unlock(); } PhysicalConnectionInfo connection = null ; try { connection = createPhysicalConnection(); } catch (SQLException e) { LOG.error ("create connection SQLException, url: " + jdbcUrl + ", errorCode " + e.getErrorCode() + ", state " + e.getSQLState(), e); errorCount++; if (errorCount > connectionErrorRetryAttempts && timeBetweenConnectErrorMillis > 0 ) { setFailContinuous(true ); if (failFast) { lock.lock(); try { notEmpty.signalAll(); } finally { lock.unlock(); } } if (breakAfterAcquireFailure) { break ; } try { Thread.sleep(timeBetweenConnectErrorMillis); } catch (InterruptedException interruptEx) { break ; } } } catch (RuntimeException e) { LOG.error ("create connection RuntimeException" , e); setFailContinuous(true ); continue ; } catch (Error e) { LOG.error ("create connection Error" , e); setFailContinuous(true ); break ; } if (connection == null ) { continue ; } boolean result = put(connection); if (!result) { JdbcUtils.close(connection.getPhysicalConnection()); LOG.info("put physical connection to pool failed." ); } errorCount = 0 ; if (closing || closed) { break ; } } } }