Remove (@Deprecate) jdbcConnectionTest property ... auto-detect it. Specification of connection test query overrides it.

pull/192/head
Brett Wooldridge 10 years ago
parent 3a0f74d114
commit 82bb7c118f

@ -78,7 +78,6 @@ public class HikariConfig implements HikariConfigMBean
private boolean isAutoCommit; private boolean isAutoCommit;
private boolean isReadOnly; private boolean isReadOnly;
private boolean isInitializationFailFast; private boolean isInitializationFailFast;
private boolean isJdbc4connectionTest;
private boolean isIsolateInternalQueries; private boolean isIsolateInternalQueries;
private boolean isRegisterMbeans; private boolean isRegisterMbeans;
private DataSource dataSource; private DataSource dataSource;
@ -102,7 +101,6 @@ public class HikariConfig implements HikariConfigMBean
connectionTimeout = CONNECTION_TIMEOUT; connectionTimeout = CONNECTION_TIMEOUT;
idleTimeout = IDLE_TIMEOUT; idleTimeout = IDLE_TIMEOUT;
isAutoCommit = true; isAutoCommit = true;
isJdbc4connectionTest = true;
isInitializationFailFast = true; isInitializationFailFast = true;
minIdle = -1; minIdle = -1;
maxPoolSize = 10; maxPoolSize = 10;
@ -423,14 +421,16 @@ public class HikariConfig implements HikariConfigMBean
this.isIsolateInternalQueries = isolate; this.isIsolateInternalQueries = isolate;
} }
@Deprecated
public boolean isJdbc4ConnectionTest() public boolean isJdbc4ConnectionTest()
{ {
return isJdbc4connectionTest; return false;
} }
@Deprecated
public void setJdbc4ConnectionTest(boolean useIsValid) public void setJdbc4ConnectionTest(boolean useIsValid)
{ {
this.isJdbc4connectionTest = useIsValid; // ignored deprecated property
} }
/** /**
@ -663,14 +663,6 @@ public class HikariConfig implements HikariConfigMBean
logger.warn("both dataSource and dataSourceClassName are specified, ignoring dataSourceClassName"); logger.warn("both dataSource and dataSourceClassName are specified, ignoring dataSourceClassName");
} }
if (connectionTestQuery != null) {
isJdbc4connectionTest = false;
}
else if (!isJdbc4connectionTest) {
logger.error("Either jdbc4ConnectionTest must be enabled or a connectionTestQuery must be specified");
throw new IllegalStateException("Either jdbc4ConnectionTest must be enabled or a connectionTestQuery must be specified");
}
if (transactionIsolationName != null) { if (transactionIsolationName != null) {
PoolUtilities.getTransactionIsolation(transactionIsolationName); PoolUtilities.getTransactionIsolation(transactionIsolationName);
} }

@ -24,6 +24,7 @@ import static com.zaxxer.hikari.util.PoolUtilities.createInstance;
import static com.zaxxer.hikari.util.PoolUtilities.createThreadPoolExecutor; import static com.zaxxer.hikari.util.PoolUtilities.createThreadPoolExecutor;
import static com.zaxxer.hikari.util.PoolUtilities.elapsedTimeMs; import static com.zaxxer.hikari.util.PoolUtilities.elapsedTimeMs;
import static com.zaxxer.hikari.util.PoolUtilities.executeSqlAutoCommit; import static com.zaxxer.hikari.util.PoolUtilities.executeSqlAutoCommit;
import static com.zaxxer.hikari.util.PoolUtilities.isJdbc40Compliant;
import static com.zaxxer.hikari.util.PoolUtilities.isJdbc41Compliant; import static com.zaxxer.hikari.util.PoolUtilities.isJdbc41Compliant;
import static com.zaxxer.hikari.util.PoolUtilities.quietlyCloseConnection; import static com.zaxxer.hikari.util.PoolUtilities.quietlyCloseConnection;
import static com.zaxxer.hikari.util.PoolUtilities.quietlySleep; import static com.zaxxer.hikari.util.PoolUtilities.quietlySleep;
@ -92,13 +93,13 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
private final String password; private final String password;
private final boolean isRecordMetrics; private final boolean isRecordMetrics;
private final boolean isRegisteredMbeans; private final boolean isRegisteredMbeans;
private final boolean isJdbc4ConnectionTest;
private final boolean isIsolateInternalQueries; private final boolean isIsolateInternalQueries;
private final long leakDetectionThreshold; private final long leakDetectionThreshold;
private volatile boolean isShutdown; private volatile boolean isShutdown;
private volatile long connectionTimeout; private volatile long connectionTimeout;
private volatile boolean isUseNetworkTimeout; private volatile boolean isUseNetworkTimeout;
private volatile boolean isUseJdbc4Validation;
/** /**
* Construct a HikariPool with the specified configuration. * Construct a HikariPool with the specified configuration.
@ -131,7 +132,6 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
this.isReadOnly = configuration.isReadOnly(); this.isReadOnly = configuration.isReadOnly();
this.isAutoCommit = configuration.isAutoCommit(); this.isAutoCommit = configuration.isAutoCommit();
this.isRegisteredMbeans = configuration.isRegisterMbeans(); this.isRegisteredMbeans = configuration.isRegisterMbeans();
this.isJdbc4ConnectionTest = configuration.isJdbc4ConnectionTest();
this.catalog = configuration.getCatalog(); this.catalog = configuration.getCatalog();
this.connectionCustomizer = initializeCustomizer(); this.connectionCustomizer = initializeCustomizer();
@ -414,6 +414,11 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
try { try {
connection = (username == null && password == null) ? dataSource.getConnection() : dataSource.getConnection(username, password); connection = (username == null && password == null) ? dataSource.getConnection() : dataSource.getConnection(username, password);
isUseNetworkTimeout = isJdbc41Compliant(connection) && (configuration.getConnectionTimeout() != Integer.MAX_VALUE); isUseNetworkTimeout = isJdbc41Compliant(connection) && (configuration.getConnectionTimeout() != Integer.MAX_VALUE);
isUseJdbc4Validation = isJdbc40Compliant(connection);
if (!isUseJdbc4Validation && configuration.getConnectionTestQuery() == null) {
LOGGER.error("JDBC4 Connection.isValid() method not supported, connection test query must be configured");
}
isUseJdbc4Validation &= configuration.getConnectionTestQuery() == null;
final boolean timeoutEnabled = (configuration.getConnectionTimeout() != Integer.MAX_VALUE); final boolean timeoutEnabled = (configuration.getConnectionTimeout() != Integer.MAX_VALUE);
final long timeoutMs = timeoutEnabled ? Math.max(250L, configuration.getConnectionTimeout()) : 0L; final long timeoutMs = timeoutEnabled ? Math.max(250L, configuration.getConnectionTimeout()) : 0L;
@ -427,9 +432,7 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
connection.setAutoCommit(isAutoCommit); connection.setAutoCommit(isAutoCommit);
connection.setTransactionIsolation(transactionIsolation); connection.setTransactionIsolation(transactionIsolation);
connection.setReadOnly(isReadOnly); connection.setReadOnly(isReadOnly);
if (catalog != null) { connection.setCatalog(catalog);
connection.setCatalog(catalog);
}
setNetworkTimeout(houseKeepingExecutorService, connection, networkTimeout, isUseNetworkTimeout); setNetworkTimeout(houseKeepingExecutorService, connection, networkTimeout, isUseNetworkTimeout);
@ -461,7 +464,7 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
final boolean timeoutEnabled = (configuration.getConnectionTimeout() != Integer.MAX_VALUE); final boolean timeoutEnabled = (configuration.getConnectionTimeout() != Integer.MAX_VALUE);
int timeoutSec = timeoutEnabled ? (int) Math.max(1L, TimeUnit.MILLISECONDS.toSeconds(timeoutMs)) : 0; int timeoutSec = timeoutEnabled ? (int) Math.max(1L, TimeUnit.MILLISECONDS.toSeconds(timeoutMs)) : 0;
if (isJdbc4ConnectionTest) { if (isUseJdbc4Validation) {
return connection.isValid(timeoutSec); return connection.isValid(timeoutSec);
} }

@ -23,8 +23,10 @@ public final class PoolUtilities
{ {
public static final boolean IS_JAVA7; public static final boolean IS_JAVA7;
private static volatile boolean IS_JDBC4; private static volatile boolean IS_JDBC40;
private static volatile boolean jdbc4checked; private static volatile boolean IS_JDBC41;
private static volatile boolean jdbc40checked;
private static volatile boolean jdbc41checked;
private static volatile boolean queryTimeoutSupported = true; private static volatile boolean queryTimeoutSupported = true;
static { static {
@ -198,6 +200,34 @@ public final class PoolUtilities
return executor; return executor;
} }
/**
* Return true if the driver appears to be JDBC 4.0 compliant.
*
* @param connection a Connection to check
* @return true if JDBC 4.1 compliance, false otherwise
* @throws SQLException re-thrown exception from Connection.getNetworkTimeout()
*/
public static boolean isJdbc40Compliant(final Connection connection) throws SQLException
{
if (jdbc40checked) {
return IS_JDBC40;
}
try {
connection.isValid(100); // This will throw AbstractMethodError or SQLException in the case of a non-JDBC 41 compliant driver
IS_JDBC40 = true;
}
catch (AbstractMethodError e) {
IS_JDBC40 = false;
}
catch (SQLFeatureNotSupportedException e) {
IS_JDBC40 = false;
}
jdbc40checked = true;
return IS_JDBC40;
}
/** /**
* Return true if the driver appears to be JDBC 4.1 compliant. * Return true if the driver appears to be JDBC 4.1 compliant.
* *
@ -207,23 +237,23 @@ public final class PoolUtilities
*/ */
public static boolean isJdbc41Compliant(final Connection connection) throws SQLException public static boolean isJdbc41Compliant(final Connection connection) throws SQLException
{ {
if (jdbc4checked) { if (jdbc41checked) {
return IS_JDBC4; return IS_JDBC41;
} }
try { try {
connection.getNetworkTimeout(); // This will throw AbstractMethodError or SQLException in the case of a non-JDBC 41 compliant driver connection.getNetworkTimeout(); // This will throw AbstractMethodError or SQLException in the case of a non-JDBC 41 compliant driver
IS_JDBC4 = true; IS_JDBC41 = true;
} }
catch (AbstractMethodError e) { catch (AbstractMethodError e) {
IS_JDBC4 = false; IS_JDBC41 = false;
} }
catch (SQLFeatureNotSupportedException e) { catch (SQLFeatureNotSupportedException e) {
IS_JDBC4 = false; IS_JDBC41 = false;
} }
jdbc4checked = true; jdbc41checked = true;
return IS_JDBC4; return IS_JDBC41;
} }
/** /**

@ -77,13 +77,17 @@ public final class TestElf
public static void resetPoolUtilities() public static void resetPoolUtilities()
{ {
try { try {
Field field = PoolUtilities.class.getDeclaredField("jdbc4checked"); Field field = PoolUtilities.class.getDeclaredField("jdbc41checked");
field.setAccessible(true); field.setAccessible(true);
field.setBoolean(null, false); field.setBoolean(null, false);
field = PoolUtilities.class.getDeclaredField("queryTimeoutSupported"); field = PoolUtilities.class.getDeclaredField("queryTimeoutSupported");
field.setAccessible(true); field.setAccessible(true);
field.setBoolean(null, true); field.setBoolean(null, true);
field = PoolUtilities.class.getDeclaredField("jdbc40checked");
field.setAccessible(true);
field.setBoolean(null, false);
} }
catch (Exception e) { catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);

@ -251,21 +251,6 @@ public class TestValidation
} }
} }
@Test
public void validateMissingTest()
{
try {
HikariConfig config = new HikariConfig();
config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource");
config.setJdbc4ConnectionTest(false);
config.validate();
Assert.fail();
}
catch (IllegalStateException ise) {
Assert.assertTrue(ise.getMessage().contains("Either jdbc4ConnectionTest"));
}
}
@Test @Test
public void validateInvalidLifetime() public void validateInvalidLifetime()
{ {

@ -78,7 +78,6 @@ public class HikariConfig implements HikariConfigMBean
private boolean isAutoCommit; private boolean isAutoCommit;
private boolean isReadOnly; private boolean isReadOnly;
private boolean isInitializationFailFast; private boolean isInitializationFailFast;
private boolean isJdbc4connectionTest;
private boolean isIsolateInternalQueries; private boolean isIsolateInternalQueries;
private boolean isRegisterMbeans; private boolean isRegisterMbeans;
private DataSource dataSource; private DataSource dataSource;
@ -102,7 +101,6 @@ public class HikariConfig implements HikariConfigMBean
connectionTimeout = CONNECTION_TIMEOUT; connectionTimeout = CONNECTION_TIMEOUT;
idleTimeout = IDLE_TIMEOUT; idleTimeout = IDLE_TIMEOUT;
isAutoCommit = true; isAutoCommit = true;
isJdbc4connectionTest = true;
isInitializationFailFast = true; isInitializationFailFast = true;
minIdle = -1; minIdle = -1;
maxPoolSize = 10; maxPoolSize = 10;
@ -423,14 +421,16 @@ public class HikariConfig implements HikariConfigMBean
this.isIsolateInternalQueries = isolate; this.isIsolateInternalQueries = isolate;
} }
@Deprecated
public boolean isJdbc4ConnectionTest() public boolean isJdbc4ConnectionTest()
{ {
return isJdbc4connectionTest; return false;
} }
@Deprecated
public void setJdbc4ConnectionTest(boolean useIsValid) public void setJdbc4ConnectionTest(boolean useIsValid)
{ {
this.isJdbc4connectionTest = useIsValid; // ignored deprecated property
} }
/** /**
@ -663,14 +663,6 @@ public class HikariConfig implements HikariConfigMBean
logger.warn("both dataSource and dataSourceClassName are specified, ignoring dataSourceClassName"); logger.warn("both dataSource and dataSourceClassName are specified, ignoring dataSourceClassName");
} }
if (connectionTestQuery != null) {
isJdbc4connectionTest = false;
}
else if (!isJdbc4connectionTest) {
logger.error("Either jdbc4ConnectionTest must be enabled or a connectionTestQuery must be specified");
throw new IllegalStateException("Either jdbc4ConnectionTest must be enabled or a connectionTestQuery must be specified");
}
if (transactionIsolationName != null) { if (transactionIsolationName != null) {
PoolUtilities.getTransactionIsolation(transactionIsolationName); PoolUtilities.getTransactionIsolation(transactionIsolationName);
} }

@ -23,6 +23,7 @@ import static com.zaxxer.hikari.util.PoolUtilities.createInstance;
import static com.zaxxer.hikari.util.PoolUtilities.createThreadPoolExecutor; import static com.zaxxer.hikari.util.PoolUtilities.createThreadPoolExecutor;
import static com.zaxxer.hikari.util.PoolUtilities.elapsedTimeMs; import static com.zaxxer.hikari.util.PoolUtilities.elapsedTimeMs;
import static com.zaxxer.hikari.util.PoolUtilities.executeSqlAutoCommit; import static com.zaxxer.hikari.util.PoolUtilities.executeSqlAutoCommit;
import static com.zaxxer.hikari.util.PoolUtilities.isJdbc40Compliant;
import static com.zaxxer.hikari.util.PoolUtilities.isJdbc41Compliant; import static com.zaxxer.hikari.util.PoolUtilities.isJdbc41Compliant;
import static com.zaxxer.hikari.util.PoolUtilities.quietlyCloseConnection; import static com.zaxxer.hikari.util.PoolUtilities.quietlyCloseConnection;
import static com.zaxxer.hikari.util.PoolUtilities.quietlySleep; import static com.zaxxer.hikari.util.PoolUtilities.quietlySleep;
@ -91,13 +92,13 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
private final String password; private final String password;
private final boolean isRecordMetrics; private final boolean isRecordMetrics;
private final boolean isRegisteredMbeans; private final boolean isRegisteredMbeans;
private final boolean isJdbc4ConnectionTest;
private final boolean isIsolateInternalQueries; private final boolean isIsolateInternalQueries;
private final long leakDetectionThreshold; private final long leakDetectionThreshold;
private volatile boolean isShutdown; private volatile boolean isShutdown;
private volatile long connectionTimeout; private volatile long connectionTimeout;
private volatile boolean isUseNetworkTimeout; private volatile boolean isUseNetworkTimeout;
private volatile boolean isUseJdbc4Validation;
/** /**
* Construct a HikariPool with the specified configuration. * Construct a HikariPool with the specified configuration.
@ -130,7 +131,6 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
this.isReadOnly = configuration.isReadOnly(); this.isReadOnly = configuration.isReadOnly();
this.isAutoCommit = configuration.isAutoCommit(); this.isAutoCommit = configuration.isAutoCommit();
this.isRegisteredMbeans = configuration.isRegisterMbeans(); this.isRegisteredMbeans = configuration.isRegisterMbeans();
this.isJdbc4ConnectionTest = configuration.isJdbc4ConnectionTest();
this.catalog = configuration.getCatalog(); this.catalog = configuration.getCatalog();
this.connectionCustomizer = initializeCustomizer(); this.connectionCustomizer = initializeCustomizer();
@ -397,6 +397,11 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
try { try {
connection = (username == null && password == null) ? dataSource.getConnection() : dataSource.getConnection(username, password); connection = (username == null && password == null) ? dataSource.getConnection() : dataSource.getConnection(username, password);
isUseNetworkTimeout = isJdbc41Compliant(connection) && (configuration.getConnectionTimeout() != Integer.MAX_VALUE); isUseNetworkTimeout = isJdbc41Compliant(connection) && (configuration.getConnectionTimeout() != Integer.MAX_VALUE);
isUseJdbc4Validation = isJdbc40Compliant(connection);
if (!isUseJdbc4Validation && configuration.getConnectionTestQuery() == null) {
LOGGER.error("JDBC4 Connection.isValid() method not supported, connection test query must be configured");
}
isUseJdbc4Validation &= configuration.getConnectionTestQuery() == null;
final boolean timeoutEnabled = (configuration.getConnectionTimeout() != Integer.MAX_VALUE); final boolean timeoutEnabled = (configuration.getConnectionTimeout() != Integer.MAX_VALUE);
final long timeoutMs = timeoutEnabled ? Math.max(250L, configuration.getConnectionTimeout()) : 0L; final long timeoutMs = timeoutEnabled ? Math.max(250L, configuration.getConnectionTimeout()) : 0L;
@ -410,9 +415,7 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
connection.setAutoCommit(isAutoCommit); connection.setAutoCommit(isAutoCommit);
connection.setTransactionIsolation(transactionIsolation); connection.setTransactionIsolation(transactionIsolation);
connection.setReadOnly(isReadOnly); connection.setReadOnly(isReadOnly);
if (catalog != null) { connection.setCatalog(catalog);
connection.setCatalog(catalog);
}
setNetworkTimeout(houseKeepingExecutorService, connection, networkTimeout, isUseNetworkTimeout); setNetworkTimeout(houseKeepingExecutorService, connection, networkTimeout, isUseNetworkTimeout);
@ -444,7 +447,7 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
final boolean timeoutEnabled = (configuration.getConnectionTimeout() != Integer.MAX_VALUE); final boolean timeoutEnabled = (configuration.getConnectionTimeout() != Integer.MAX_VALUE);
int timeoutSec = timeoutEnabled ? (int) Math.max(1L, TimeUnit.MILLISECONDS.toSeconds(timeoutMs)) : 0; int timeoutSec = timeoutEnabled ? (int) Math.max(1L, TimeUnit.MILLISECONDS.toSeconds(timeoutMs)) : 0;
if (isJdbc4ConnectionTest) { if (isUseJdbc4Validation) {
return connection.isValid(timeoutSec); return connection.isValid(timeoutSec);
} }

@ -20,8 +20,10 @@ import org.slf4j.Logger;
public final class PoolUtilities public final class PoolUtilities
{ {
private static volatile boolean IS_JDBC4; private static volatile boolean IS_JDBC40;
private static volatile boolean jdbc4checked; private static volatile boolean IS_JDBC41;
private static volatile boolean jdbc40checked;
private static volatile boolean jdbc41checked;
private static volatile boolean queryTimeoutSupported = true; private static volatile boolean queryTimeoutSupported = true;
/** /**
@ -180,6 +182,31 @@ public final class PoolUtilities
return executor; return executor;
} }
/**
* Return true if the driver appears to be JDBC 4.0 compliant.
*
* @param connection a Connection to check
* @return true if JDBC 4.1 compliance, false otherwise
* @throws SQLException re-thrown exception from Connection.getNetworkTimeout()
*/
public static boolean isJdbc40Compliant(final Connection connection) throws SQLException
{
if (jdbc40checked) {
return IS_JDBC40;
}
try {
connection.isValid(100); // This will throw AbstractMethodError or SQLException in the case of a non-JDBC 41 compliant driver
IS_JDBC40 = true;
}
catch (AbstractMethodError | SQLFeatureNotSupportedException e) {
IS_JDBC40 = false;
}
jdbc40checked = true;
return IS_JDBC40;
}
/** /**
* Return true if the driver appears to be JDBC 4.1 compliant. * Return true if the driver appears to be JDBC 4.1 compliant.
* *
@ -189,20 +216,20 @@ public final class PoolUtilities
*/ */
public static boolean isJdbc41Compliant(final Connection connection) throws SQLException public static boolean isJdbc41Compliant(final Connection connection) throws SQLException
{ {
if (jdbc4checked) { if (jdbc41checked) {
return IS_JDBC4; return IS_JDBC41;
} }
try { try {
connection.getNetworkTimeout(); // This will throw AbstractMethodError or SQLException in the case of a non-JDBC 41 compliant driver connection.getNetworkTimeout(); // This will throw AbstractMethodError or SQLException in the case of a non-JDBC 41 compliant driver
IS_JDBC4 = true; IS_JDBC41 = true;
} }
catch (AbstractMethodError | SQLFeatureNotSupportedException e) { catch (AbstractMethodError | SQLFeatureNotSupportedException e) {
IS_JDBC4 = false; IS_JDBC41 = false;
} }
jdbc4checked = true; jdbc41checked = true;
return IS_JDBC4; return IS_JDBC41;
} }
/** /**

@ -77,13 +77,17 @@ public final class TestElf
public static void resetPoolUtilities() public static void resetPoolUtilities()
{ {
try { try {
Field field = PoolUtilities.class.getDeclaredField("jdbc4checked"); Field field = PoolUtilities.class.getDeclaredField("jdbc41checked");
field.setAccessible(true); field.setAccessible(true);
field.setBoolean(null, false); field.setBoolean(null, false);
field = PoolUtilities.class.getDeclaredField("queryTimeoutSupported"); field = PoolUtilities.class.getDeclaredField("queryTimeoutSupported");
field.setAccessible(true); field.setAccessible(true);
field.setBoolean(null, true); field.setBoolean(null, true);
field = PoolUtilities.class.getDeclaredField("jdbc40checked");
field.setAccessible(true);
field.setBoolean(null, false);
} }
catch (Exception e) { catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);

@ -251,21 +251,6 @@ public class TestValidation
} }
} }
@Test
public void validateMissingTest()
{
try {
HikariConfig config = new HikariConfig();
config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource");
config.setJdbc4ConnectionTest(false);
config.validate();
Assert.fail();
}
catch (IllegalStateException ise) {
Assert.assertTrue(ise.getMessage().contains("Either jdbc4ConnectionTest"));
}
}
@Test @Test
public void validateInvalidLifetime() public void validateInvalidLifetime()
{ {

Loading…
Cancel
Save