Skip to content

Commit

Permalink
add more onFatalError info.
Browse files Browse the repository at this point in the history
  • Loading branch information
wenshao committed Nov 21, 2017
1 parent 3fb484a commit 882470b
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -1493,8 +1496,11 @@ void initStatement(DruidPooledConnection conn, Statement stmt) throws SQLExcepti
}
}

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;

Expand Down
105 changes: 66 additions & 39 deletions src/main/java/com/alibaba/druid/pool/DruidDataSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
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;
Expand Down Expand Up @@ -1416,7 +1416,20 @@ private DruidPooledConnection getConnectionInternal(long maxWait) throws SQLExce
&& 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++;
Expand Down Expand Up @@ -1498,7 +1511,7 @@ private DruidPooledConnection getConnectionInternal(long maxWait) throws SQLExce
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();
Expand All @@ -1516,51 +1529,65 @@ public void handleConnectionException(DruidPooledConnection pooledConnection, Th

// 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();
}
}
handleFatalError(pooledConnection, sqlEx, sql);
}

boolean requireDiscard = false;
final ReentrantLock lock = pooledConnection.lock;
lock.lock();
try {
if ((!pooledConnection.isClosed()) || !pooledConnection.isDisable()) {
holder.setDiscard(true);
pooledConnection.disable(t);
requireDiscard = true;
}
throw sqlEx;
} else {
throw new SQLException("Error", t);
}
}

onFatalError = true;
} finally {
lock.unlock();
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();
}
}

if (requireDiscard) {
if (holder.statementTrace != null) {
for (Statement stmt : holder.statementTrace) {
JdbcUtils.close(stmt);
}
}
long lastErrorTimeMillis = this.lastErrorTimeMillis;
if (lastErrorTimeMillis == 0) {
lastErrorTimeMillis = System.currentTimeMillis();
}

this.discardConnection(holder.getConnection());
holder.setDiscard(true);
}
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();
}

LOG.error("discard connection", sqlEx);
if (requireDiscard) {
if (holder.statementTrace != null) {
for (Statement stmt : holder.statementTrace) {
JdbcUtils.close(stmt);
}
}

throw sqlEx;
} else {
throw new SQLException("Error", t);
this.discardConnection(holder.getConnection());
holder.setDiscard(true);
}

LOG.error("discard connection", error);
}

/**
Expand Down
Loading

0 comments on commit 882470b

Please sign in to comment.