Exploit Connection network timeout if available.

pull/192/head
Brett Wooldridge 11 years ago
parent 9ba1f277cc
commit ca9b82970c

@ -94,6 +94,7 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
private volatile boolean isShutdown;
private volatile long connectionTimeout;
private volatile boolean isJdbc41Compliant;
/**
* Construct a HikariPool with the specified configuration.
@ -430,6 +431,7 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
connection = (username == null && password == null) ? dataSource.getConnection() : dataSource.getConnection(username, password);
transactionIsolation = (transactionIsolation < 0 ? connection.getTransactionIsolation() : transactionIsolation);
connectionCustomizer.customize(connection);
isJdbc41Compliant = PoolUtilities.isJdbc41Compliant(connection);
executeSqlAutoCommit(connection, configuration.getConnectionInitSql());
@ -474,21 +476,32 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
return connection.isValid((int) TimeUnit.MILLISECONDS.toSeconds(timeoutMs));
}
int networkTimeout = 0;
if (isJdbc41Compliant) {
networkTimeout = connection.getNetworkTimeout();
connection.setNetworkTimeout(houseKeepingExecutorService, timeoutEnabled ? (int) timeoutMs : 0);
}
Statement statement = connection.createStatement();
try {
statement.setQueryTimeout((int) TimeUnit.MILLISECONDS.toSeconds(timeoutMs));
statement.executeQuery(configuration.getConnectionTestQuery());
return true;
}
finally {
statement.close();
if (isIsolateInternalQueries && !isAutoCommit) {
connection.rollback();
}
}
if (isIsolateInternalQueries && !isAutoCommit) {
connection.rollback();
}
if (isJdbc41Compliant) {
connection.setNetworkTimeout(houseKeepingExecutorService, networkTimeout);
}
return true;
}
catch (SQLException e) {
LOGGER.warn("Exception during keep alive check, that means the connection must be dead.", e);
LOGGER.warn("Exception during keep alive check, that means the connection ({}) must be dead.", connection, e);
return false;
}
}

@ -19,6 +19,9 @@ public final class PoolUtilities
{
public static final boolean IS_JAVA7;
private static volatile boolean IS_JDBC4;
private static volatile boolean jdbc4checked;
static {
boolean b = false;
try {
@ -30,7 +33,12 @@ public final class PoolUtilities
IS_JAVA7 = b;
}
public static void quietlyCloseConnection(Connection connection)
/**
* Close connection and eat any exception.
*
* @param connection the connection to close
*/
public static void quietlyCloseConnection(final Connection connection)
{
if (connection != null) {
try {
@ -164,10 +172,27 @@ public final class PoolUtilities
threadFactory = new DefaultThreadFactory(threadName, true);
}
int processors = Math.max(1, Runtime.getRuntime().availableProcessors() / 4);
LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>(queueSize);
ThreadPoolExecutor executor = new ThreadPoolExecutor(processors, processors, 5, TimeUnit.SECONDS, queue, threadFactory, policy);
ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 5, TimeUnit.SECONDS, queue, threadFactory, policy);
executor.allowCoreThreadTimeOut(true);
return executor;
}
public static boolean isJdbc41Compliant(Connection connection)
{
if (jdbc4checked) {
return IS_JDBC4;
}
try {
connection.getNetworkTimeout(); // This will throw AbstractMethodError or SQLException in the case of a non-JDBC 41 compliant driver
IS_JDBC4 = true;
}
catch (Exception e) {
IS_JDBC4 = false;
}
jdbc4checked = true;
return IS_JDBC4;
}
}

@ -93,6 +93,7 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
private volatile boolean isShutdown;
private volatile long connectionTimeout;
private volatile boolean isJdbc41Compliant;
/**
* Construct a HikariPool with the specified configuration.
@ -368,11 +369,7 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
@Override
public void closeIdleConnections()
{
connectionBag.values(STATE_NOT_IN_USE).forEach(bagEntry -> {
if (connectionBag.reserve(bagEntry)) {
closeConnection(bagEntry);
}
});
connectionBag.values(STATE_NOT_IN_USE).stream().filter(p -> connectionBag.reserve(p)).forEach(bagEntry -> closeConnection(bagEntry));
}
/** {@inheritDoc} */
@ -414,10 +411,10 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
Connection connection = null;
try {
connection = (username == null && password == null) ? dataSource.getConnection() : dataSource.getConnection(username, password);
transactionIsolation = (transactionIsolation < 0 ? connection.getTransactionIsolation() : transactionIsolation);
connectionCustomizer.customize(connection);
isJdbc41Compliant = PoolUtilities.isJdbc41Compliant(connection);
executeSqlAutoCommit(connection, configuration.getConnectionInitSql());
@ -462,19 +459,28 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
return connection.isValid((int) TimeUnit.MILLISECONDS.toSeconds(timeoutMs));
}
int networkTimeout = 0;
if (isJdbc41Compliant) {
networkTimeout = connection.getNetworkTimeout();
connection.setNetworkTimeout(houseKeepingExecutorService, timeoutEnabled ? (int) timeoutMs : 0);
}
try (Statement statement = connection.createStatement()) {
statement.setQueryTimeout((int) TimeUnit.MILLISECONDS.toSeconds(timeoutMs));
statement.executeQuery(configuration.getConnectionTestQuery());
return true;
}
finally {
if (isIsolateInternalQueries && !isAutoCommit) {
connection.rollback();
}
if (isIsolateInternalQueries && !isAutoCommit) {
connection.rollback();
}
if (isJdbc41Compliant) {
connection.setNetworkTimeout(houseKeepingExecutorService, networkTimeout);
}
return true;
}
catch (SQLException e) {
LOGGER.warn("Exception during keep alive check, that means the connection (" + connection + ") must be dead.", e);
LOGGER.warn("Exception during keep alive check, that means the connection ({}) must be dead.", connection, e);
return false;
}
}

@ -16,6 +16,9 @@ import javax.sql.DataSource;
public final class PoolUtilities
{
private static volatile boolean IS_JDBC4;
private static volatile boolean jdbc4checked;
/**
* Close connection and eat any exception.
*
@ -151,10 +154,27 @@ public final class PoolUtilities
threadFactory = new DefaultThreadFactory(threadName, true);
}
int processors = Math.max(1, Runtime.getRuntime().availableProcessors() / 4);
LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>(queueSize);
ThreadPoolExecutor executor = new ThreadPoolExecutor(processors, processors, 5, TimeUnit.SECONDS, queue, threadFactory, policy);
ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 5, TimeUnit.SECONDS, queue, threadFactory, policy);
executor.allowCoreThreadTimeOut(true);
return executor;
}
public static boolean isJdbc41Compliant(Connection connection)
{
if (jdbc4checked) {
return IS_JDBC4;
}
try {
connection.getNetworkTimeout(); // This will throw AbstractMethodError or SQLException in the case of a non-JDBC 41 compliant driver
IS_JDBC4 = true;
}
catch (AbstractMethodError | SQLException e) {
IS_JDBC4 = false;
}
jdbc4checked = true;
return IS_JDBC4;
}
}

Loading…
Cancel
Save