DruidDataSource onFatalErrorMaxActive support.

This commit is contained in:
wenshao
2017-11-20 15:30:28 +08:00
parent 67a9742679
commit a2174055a7
4 changed files with 126 additions and 50 deletions
@@ -255,6 +255,8 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
protected boolean initVariants = false;
protected boolean initGlobalVariants = false;
protected volatile boolean onFatalError = false;
protected volatile int onFatalErrorMaxActive = 0;
public DruidAbstractDataSource(boolean lockFair){
lock = new ReentrantLock(lockFair);
@@ -1955,6 +1957,18 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
this.failFast = failFast;
}
public int getOnFatalErrorMaxActive() {
return onFatalErrorMaxActive;
}
public void setOnFatalErrorMaxActive(int onFatalErrorMaxActive) {
this.onFatalErrorMaxActive = onFatalErrorMaxActive;
}
public boolean isOnFatalError() {
return onFatalError;
}
public static class PhysicalConnectionInfo {
private Connection connection;
private long connectStartNanos;
@@ -90,36 +90,30 @@ import com.alibaba.druid.wall.WallProviderStatValue;
*/
public class DruidDataSource extends DruidAbstractDataSource implements DruidDataSourceMBean, ManagedDataSource, Referenceable, Closeable, Cloneable, ConnectionPoolDataSource, MBeanRegistration {
private final static Log LOG = LogFactory.getLog(DruidDataSource.class);
private static final long serialVersionUID = 1L;
private final static Log LOG = LogFactory.getLog(DruidDataSource.class);
private static final long serialVersionUID = 1L;
// stats
private final AtomicLong recycleErrorCount = new AtomicLong();
private long connectCount = 0L;
private long closeCount = 0L;
private final AtomicLong connectErrorCount = new AtomicLong();
private long recycleCount = 0L;
private long removeAbandonedCount = 0L;
private long notEmptyWaitCount = 0L;
private long notEmptySignalCount = 0L;
private long notEmptyWaitNanos = 0L;
private int keepAliveCheckCount = 0;
private int activePeak = 0;
private long activePeakTime = 0;
private int poolingPeak = 0;
private long poolingPeakTime = 0;
private final AtomicLong recycleErrorCount = new AtomicLong();
private long connectCount = 0L;
private long closeCount = 0L;
private final AtomicLong connectErrorCount = new AtomicLong();
private long recycleCount = 0L;
private long removeAbandonedCount = 0L;
private long notEmptyWaitCount = 0L;
private long notEmptySignalCount = 0L;
private long notEmptyWaitNanos = 0L;
private int keepAliveCheckCount = 0;
private int activePeak = 0;
private long activePeakTime = 0;
private int poolingPeak = 0;
private long poolingPeakTime = 0;
// store
private volatile DruidConnectionHolder[] connections;
private int poolingCount = 0;
private int activeCount = 0;
private long discardCount = 0;
private int notEmptyWaitThreadCount = 0;
private int notEmptyWaitThreadPeak = 0;
private int poolingCount = 0;
private int activeCount = 0;
private long discardCount = 0;
private int notEmptyWaitThreadCount = 0;
private int notEmptyWaitThreadPeak = 0;
//
private DruidConnectionHolder[] evictConnections;
private DruidConnectionHolder[] keepAliveConnections;
@@ -135,30 +129,27 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
private LogStatsThread logStatsThread;
private int createTaskCount;
private final CountDownLatch initedLatch = new CountDownLatch(2);
private final CountDownLatch initedLatch = new CountDownLatch(2);
private volatile boolean enable = true;
private volatile boolean enable = true;
private boolean resetStatEnable = true;
private final AtomicLong resetCount = new AtomicLong();
private boolean resetStatEnable = true;
private final AtomicLong resetCount = new AtomicLong();
private String initStackTrace;
private volatile boolean closing = false;
private volatile boolean closed = false;
private long closeTimeMillis = -1L;
private volatile boolean closing = false;
private volatile boolean closed = false;
private long closeTimeMillis = -1L;
protected JdbcDataSourceStat dataSourceStat;
private boolean useGlobalDataSourceStat = false;
private boolean mbeanRegistered = false;
public static ThreadLocal<Long> waitNanosLocal = new ThreadLocal<Long>();
private boolean logDifferentThread = true;
private volatile boolean keepAlive = false;
private boolean asyncInit = false;
private boolean useGlobalDataSourceStat = false;
private boolean mbeanRegistered = false;
public static ThreadLocal<Long> waitNanosLocal = new ThreadLocal<Long>();
private boolean logDifferentThread = true;
private volatile boolean keepAlive = false;
private boolean asyncInit = false;
protected boolean killWhenSocketReadTimeout = false;
public DruidDataSource(){
@@ -1371,12 +1362,19 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
}
try {
if (maxWaitThreadCount > 0) {
if (notEmptyWaitThreadCount >= maxWaitThreadCount) {
if (maxWaitThreadCount > 0
&& notEmptyWaitThreadCount >= maxWaitThreadCount)
{
connectErrorCount.incrementAndGet();
throw new SQLException("maxWaitThreadCount " + maxWaitThreadCount + ", current wait Thread count "
+ lock.getQueueLength());
}
}
if (onFatalError
&& onFatalErrorMaxActive > 0
&& activeCount >= onFatalErrorMaxActive) {
connectErrorCount.incrementAndGet();
throw new SQLException("onFatalError, activeCount " + activeCount + ", onFatalErrorMaxActive " + onFatalErrorMaxActive);
}
connectCount++;
@@ -1482,6 +1480,8 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
pooledConnection.disable(t);
requireDiscard = true;
}
onFatalError = true;
} finally {
lock.unlock();
}
@@ -61,7 +61,7 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
protected TransactionInfo transactionInfo;
private final boolean dupCloseLogEnable;
protected volatile boolean traceEnable = false;
private boolean disable = false;
private volatile boolean disable = false;
private boolean closed = false;
protected final Thread ownerThread;
private long connectedTimeMillis;
@@ -1208,9 +1208,13 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
final void afterExecute() {
final DruidConnectionHolder holder = this.holder;
if (holder != null && holder.dataSource.removeAbandoned) {
running = false;
holder.lastActiveTimeMillis = System.currentTimeMillis();
if (holder != null) {
DruidAbstractDataSource dataSource = holder.dataSource;
if (dataSource.removeAbandoned) {
running = false;
holder.lastActiveTimeMillis = System.currentTimeMillis();
}
dataSource.onFatalError = false;
}
}