add more onFatalError info.

This commit is contained in:
wenshao
2017-11-21 16:55:00 +08:00
parent 3fb484aa88
commit 882470b1ce
6 changed files with 144 additions and 88 deletions
@@ -256,6 +256,9 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
protected boolean initGlobalVariants = false;
protected volatile boolean onFatalError = false;
protected volatile int onFatalErrorMaxActive = 0;
protected volatile long lastFatalErrorTimeMillis = 0;
protected volatile String lastFatalErrorSql = null;
protected volatile Throwable lastFatalError = null;
protected static AtomicIntegerFieldUpdater<DruidAbstractDataSource> directCreateCountUpdater = AtomicIntegerFieldUpdater.newUpdater(DruidAbstractDataSource.class, "directCreateCount");
protected static AtomicIntegerFieldUpdater<DruidAbstractDataSource> createCountUpdater = AtomicIntegerFieldUpdater.newUpdater(DruidAbstractDataSource.class, "creatingCount");
@@ -1493,8 +1496,11 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
}
}
public abstract void handleConnectionException(DruidPooledConnection pooledConnection, Throwable t)
throws SQLException;
public void handleConnectionException(DruidPooledConnection conn, Throwable t) throws SQLException {
handleConnectionException(conn, t, null);
}
public abstract void handleConnectionException(DruidPooledConnection conn, Throwable t, String sql) throws SQLException;
protected abstract void recycle(DruidPooledConnection pooledConnection) throws SQLException;
@@ -23,9 +23,9 @@ import java.security.PrivilegedAction;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
import java.util.concurrent.locks.Lock;
@@ -1416,7 +1416,20 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
&& onFatalErrorMaxActive > 0
&& activeCount >= onFatalErrorMaxActive) {
connectErrorCountUpdater.incrementAndGet(this);
throw new SQLException("onFatalError, activeCount " + activeCount + ", onFatalErrorMaxActive " + onFatalErrorMaxActive);
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String errorMsg = "onFatalError, activeCount " + activeCount
+ ", onFatalErrorMaxActive " + onFatalErrorMaxActive;
if (lastFatalErrorTimeMillis > 0) {
errorMsg += ", time '" + format.format(new Date(lastFatalErrorTimeMillis)) + "'";
}
if (lastFatalErrorSql != null) {
errorMsg += ", sql \n" + lastFatalErrorSql;
}
throw new SQLException(errorMsg, lastFatalError);
}
connectCount++;
@@ -1498,7 +1511,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
return poolalbeConnection;
}
public void handleConnectionException(DruidPooledConnection pooledConnection, Throwable t) throws SQLException {
public void handleConnectionException(DruidPooledConnection pooledConnection, Throwable t, String sql) throws SQLException {
final DruidConnectionHolder holder = pooledConnection.getConnectionHolder();
errorCount.incrementAndGet();
@@ -1516,45 +1529,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
// exceptionSorter.isExceptionFatal
if (exceptionSorter != null && exceptionSorter.isExceptionFatal(sqlEx)) {
if (pooledConnection.isTraceEnable()) {
activeConnectionLock.lock();
try {
if (pooledConnection.isTraceEnable()) {
activeConnections.remove(pooledConnection);
pooledConnection.setTraceEnable(false);
}
} finally {
activeConnectionLock.unlock();
}
}
boolean requireDiscard = false;
final ReentrantLock lock = pooledConnection.lock;
lock.lock();
try {
if ((!pooledConnection.isClosed()) || !pooledConnection.isDisable()) {
holder.setDiscard(true);
pooledConnection.disable(t);
requireDiscard = true;
}
onFatalError = true;
} finally {
lock.unlock();
}
if (requireDiscard) {
if (holder.statementTrace != null) {
for (Statement stmt : holder.statementTrace) {
JdbcUtils.close(stmt);
}
}
this.discardConnection(holder.getConnection());
holder.setDiscard(true);
}
LOG.error("discard connection", sqlEx);
handleFatalError(pooledConnection, sqlEx, sql);
}
throw sqlEx;
@@ -1563,6 +1538,58 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
}
}
protected final void handleFatalError(DruidPooledConnection conn, SQLException error, String sql) throws SQLException {
final DruidConnectionHolder holder = conn.holder;
if (conn.isTraceEnable()) {
activeConnectionLock.lock();
try {
if (conn.isTraceEnable()) {
activeConnections.remove(conn);
conn.setTraceEnable(false);
}
} finally {
activeConnectionLock.unlock();
}
}
long lastErrorTimeMillis = this.lastErrorTimeMillis;
if (lastErrorTimeMillis == 0) {
lastErrorTimeMillis = System.currentTimeMillis();
}
boolean requireDiscard = false;
final ReentrantLock lock = conn.lock;
lock.lock();
try {
if ((!conn.isClosed()) || !conn.isDisable()) {
holder.setDiscard(true);
conn.disable(error);
requireDiscard = true;
}
lastFatalErrorTimeMillis = lastErrorTimeMillis;
onFatalError = true;
lastFatalError = error;
lastFatalErrorSql = sql;
} finally {
lock.unlock();
}
if (requireDiscard) {
if (holder.statementTrace != null) {
for (Statement stmt : holder.statementTrace) {
JdbcUtils.close(stmt);
}
}
this.discardConnection(holder.getConnection());
holder.setDiscard(true);
}
LOG.error("discard connection", error);
}
/**
* 回收连接
*/
@@ -121,12 +121,16 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
}
public SQLException handleException(Throwable t) throws SQLException {
return handleException(t, null);
}
public SQLException handleException(Throwable t, String sql) throws SQLException {
final DruidConnectionHolder holder = this.holder;
//
if (holder != null) {
DruidAbstractDataSource dataSource = holder.getDataSource();
dataSource.handleConnectionException(this, t);
dataSource.handleConnectionException(this, t, sql);
}
if (t instanceof SQLException) {
@@ -151,7 +155,7 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
try {
rawStatement.clearParameters();
} catch (SQLException ex) {
this.handleException(ex);
this.handleException(ex, null);
if (rawStatement.getConnection().isClosed()) {
return;
}
@@ -184,7 +188,7 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
//In this case, the exception is desired to be properly handled to remove the unusable connection from the pool.
stmt.closeInternal();
} catch (SQLException ex) {
this.handleException(ex);
this.handleException(ex, null);
throw ex;
} finally {
holder.getDataSource().incrementClosedPreparedStatementCount();
@@ -345,7 +349,7 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
stmtHolder = new PreparedStatementHolder(key, conn.prepareStatement(sql));
holder.getDataSource().incrementPreparedStatementCount();
} catch (SQLException ex) {
handleException(ex);
handleException(ex, sql);
}
}
@@ -384,7 +388,7 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
resultSetConcurrency));
holder.getDataSource().incrementPreparedStatementCount();
} catch (SQLException ex) {
handleException(ex);
handleException(ex, sql);
}
}
@@ -419,7 +423,7 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
resultSetHoldability));
holder.getDataSource().incrementPreparedStatementCount();
} catch (SQLException ex) {
handleException(ex);
handleException(ex, sql);
}
}
@@ -450,7 +454,7 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
stmtHolder = new PreparedStatementHolder(key, conn.prepareStatement(sql, columnIndexes));
holder.getDataSource().incrementPreparedStatementCount();
} catch (SQLException ex) {
handleException(ex);
handleException(ex, sql);
}
}
@@ -481,7 +485,7 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
stmtHolder = new PreparedStatementHolder(key, conn.prepareStatement(sql, columnNames));
holder.getDataSource().incrementPreparedStatementCount();
} catch (SQLException ex) {
handleException(ex);
handleException(ex, sql);
}
}
@@ -512,7 +516,7 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
stmtHolder = new PreparedStatementHolder(key, conn.prepareStatement(sql, autoGeneratedKeys));
holder.getDataSource().incrementPreparedStatementCount();
} catch (SQLException ex) {
handleException(ex);
handleException(ex, sql);
}
}
@@ -545,7 +549,7 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
stmtHolder = new PreparedStatementHolder(key, conn.prepareCall(sql));
holder.getDataSource().incrementPreparedStatementCount();
} catch (SQLException ex) {
handleException(ex);
handleException(ex, sql);
}
}
@@ -580,7 +584,7 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
resultSetHoldability));
holder.getDataSource().incrementPreparedStatementCount();
} catch (SQLException ex) {
handleException(ex);
handleException(ex, sql);
}
}
@@ -613,7 +617,7 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
conn.prepareCall(sql, resultSetType, resultSetConcurrency));
holder.getDataSource().incrementPreparedStatementCount();
} catch (SQLException ex) {
handleException(ex);
handleException(ex, sql);
}
}
@@ -635,7 +639,7 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
try {
stmt = conn.createStatement();
} catch (SQLException ex) {
handleException(ex);
handleException(ex, null);
}
holder.getDataSource().initStatement(this, stmt);
@@ -655,7 +659,7 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
try {
stmt = conn.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
} catch (SQLException ex) {
handleException(ex);
handleException(ex, null);
}
holder.getDataSource().initStatement(this, stmt);
@@ -674,7 +678,7 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
try {
stmt = conn.createStatement(resultSetType, resultSetConcurrency);
} catch (SQLException ex) {
handleException(ex);
handleException(ex, null);
}
holder.getDataSource().initStatement(this, stmt);
@@ -708,7 +712,7 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
conn.setAutoCommit(autoCommit);
holder.setUnderlyingAutoCommit(autoCommit);
} catch (SQLException ex) {
handleException(ex);
handleException(ex, null);
}
}
@@ -744,7 +748,7 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
try {
conn.commit();
} catch (SQLException ex) {
handleException(ex);
handleException(ex, null);
} finally {
handleEndTransaction(dataSource, null);
}
@@ -776,7 +780,7 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
try {
conn.rollback();
} catch (SQLException ex) {
handleException(ex);
handleException(ex, null);
} finally {
handleEndTransaction(dataSource, null);
}
@@ -789,7 +793,7 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
try {
return conn.setSavepoint(name);
} catch (SQLException ex) {
handleException(ex);
handleException(ex, null);
return null; // never arrive
}
}
@@ -806,7 +810,7 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
try {
conn.rollback(savepoint);
} catch (SQLException ex) {
handleException(ex);
handleException(ex, null);
} finally {
handleEndTransaction(dataSource, savepoint);
}
@@ -831,7 +835,7 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
try {
conn.releaseSavepoint(savepoint);
} catch (SQLException ex) {
handleException(ex);
handleException(ex, null);
}
}
@@ -842,7 +846,7 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
try {
return conn.createClob();
} catch (SQLException ex) {
handleException(ex);
handleException(ex, null);
return null; // never arrive
}
}
@@ -885,7 +889,7 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
try {
conn.setReadOnly(readOnly);
} catch (SQLException ex) {
handleException(ex);
handleException(ex, null);
}
holder.setUnderlyingReadOnly(readOnly);
@@ -905,7 +909,7 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
try {
conn.setCatalog(catalog);
} catch (SQLException ex) {
handleException(ex);
handleException(ex, null);
}
}
@@ -930,7 +934,7 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
try {
conn.setTransactionIsolation(level);
} catch (SQLException ex) {
handleException(ex);
handleException(ex, null);
}
holder.setUnderlyingTransactionIsolation(level);
}
@@ -955,7 +959,7 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
try {
conn.clearWarnings();
} catch (SQLException ex) {
handleException(ex);
handleException(ex, null);
}
}
@@ -1006,7 +1010,7 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
try {
return conn.setSavepoint();
} catch (SQLException ex) {
handleException(ex);
handleException(ex, null);
return null;
}
}
@@ -195,7 +195,7 @@ public class DruidPooledPreparedStatement extends DruidPooledStatement implement
currentFetchSize = defaultFetchSize;
}
} catch (Exception e) {
this.conn.handleException(e);
this.conn.handleException(e, null);
}
}
@@ -66,13 +66,25 @@ public class DruidPooledStatement extends PoolableWrapper implements Statement {
}
protected SQLException checkException(Throwable error) throws SQLException {
String sql = null;
if (this instanceof DruidPooledPreparedStatement) {
sql = ((DruidPooledPreparedStatement) this).getSql();
}
handleScoketTimeout(error);
exceptionCount++;
return conn.handleException(error);
return conn.handleException(error, sql);
}
private void handleScoketTimeout(Throwable error) throws SQLException {
protected SQLException checkException(Throwable error, String sql) throws SQLException {
handleScoketTimeout(error);
exceptionCount++;
return conn.handleException(error, sql);
}
protected void handleScoketTimeout(Throwable error) throws SQLException {
if (this.conn == null
|| this.conn.transactionInfo != null
|| this.conn.holder == null) {
@@ -228,7 +240,7 @@ public class DruidPooledStatement extends PoolableWrapper implements Statement {
} catch (Throwable t) {
errorCheck(t);
throw checkException(t);
throw checkException(t, sql);
} finally {
conn.afterExecute();
}
@@ -247,7 +259,7 @@ public class DruidPooledStatement extends PoolableWrapper implements Statement {
} catch (Throwable t) {
errorCheck(t);
throw checkException(t);
throw checkException(t, sql);
} finally {
conn.afterExecute();
}
@@ -298,7 +310,7 @@ public class DruidPooledStatement extends PoolableWrapper implements Statement {
} catch (Throwable t) {
errorCheck(t);
throw checkException(t);
throw checkException(t, sql);
} finally {
conn.afterExecute();
}
@@ -317,7 +329,7 @@ public class DruidPooledStatement extends PoolableWrapper implements Statement {
} catch (Throwable t) {
errorCheck(t);
throw checkException(t);
throw checkException(t, sql);
} finally {
conn.afterExecute();
}
@@ -336,7 +348,7 @@ public class DruidPooledStatement extends PoolableWrapper implements Statement {
} catch (Throwable t) {
errorCheck(t);
throw checkException(t);
throw checkException(t, sql);
} finally {
conn.afterExecute();
}
@@ -355,7 +367,7 @@ public class DruidPooledStatement extends PoolableWrapper implements Statement {
} catch (Throwable t) {
errorCheck(t);
throw checkException(t);
throw checkException(t, sql);
} finally {
conn.afterExecute();
}
@@ -374,7 +386,7 @@ public class DruidPooledStatement extends PoolableWrapper implements Statement {
} catch (Throwable t) {
errorCheck(t);
throw checkException(t);
throw checkException(t, sql);
} finally {
conn.afterExecute();
}
@@ -393,7 +405,7 @@ public class DruidPooledStatement extends PoolableWrapper implements Statement {
} catch (Throwable t) {
errorCheck(t);
throw checkException(t);
throw checkException(t, sql);
} finally {
conn.afterExecute();
}
@@ -547,7 +559,7 @@ public class DruidPooledStatement extends PoolableWrapper implements Statement {
} catch (Throwable t) {
errorCheck(t);
throw checkException(t);
throw checkException(t, sql);
}
}
@@ -677,7 +689,7 @@ public class DruidPooledStatement extends PoolableWrapper implements Statement {
try {
stmt.addBatch(sql);
} catch (Throwable t) {
throw checkException(t);
throw checkException(t, sql);
}
}