Merge branch 'dev' of github.com:brettwooldridge/HikariCP into dev

* 'dev' of github.com:brettwooldridge/HikariCP:
  Add IBM DB2 DataSource class to table.
  Minor cleanup.
  Minor cleanup.
  More metrics groundwork.
  Revert "Speculative fix for cross-thread visibility issue."
pull/131/head
Brett Wooldridge 11 years ago
commit e79b4f7f16

@ -288,6 +288,7 @@ We recommended using ``dataSourceClassName`` instead of ``driverClassName``/``jd
| Database | Driver | *DataSource* class |
|:---------------- |:------------ |:-------------------|
| Apache Derby | Derby | org.apache.derby.jdbc.ClientDataSource |
| IBM DB2 | DB2 | com.ibm.db2.jcc.DB2SimpleDataSource |
| H2 | H2 | org.h2.jdbcx.JdbcDataSource |
| HSQLDB | HSQLDB | org.hsqldb.jdbc.JDBCDataSource |
| MariaDB & MySQL | MariaDB | org.mariadb.jdbc.MySQLDataSource |

@ -65,6 +65,7 @@ public class HikariConfig implements HikariConfigMBean
private String dataSourceJndiName;
private String driverClassName;
private String jdbcUrl;
private String metricsTrackerClassName;
private String password;
private String poolName;
private String transactionIsolationName;
@ -102,6 +103,7 @@ public class HikariConfig implements HikariConfigMBean
maxLifetime = MAX_LIFETIME;
isRecordMetrics = false;
transactionIsolation = -1;
metricsTrackerClassName = "com.zaxxer.hikari.metrics.CodaHaleMetricsTracker";
customizer = new IConnectionCustomizer() {
@Override
public void customize(Connection connection) throws SQLException
@ -521,6 +523,28 @@ public class HikariConfig implements HikariConfigMBean
this.maxPoolSize = maxPoolSize;
}
/**
* Get the name of the class that implements the IMetricsTracker interface to
* be used for metrics tracking.
*
* @return the name of the class that implements the IMetricsTracker interface
*/
public String getMetricsTrackerClassName()
{
return metricsTrackerClassName;
}
/**
* Set the name of the class that implements the IMetricsTracker interface to
* be used for metrics tracking.
*
* @param className the name of the class that implements the IMetricsTracker interface
*/
public void setMetricsTrackerClassName(String className)
{
this.metricsTrackerClassName = className;
}
/** {@inheritDoc} */
@Override
public int getMinimumIdle()

@ -46,7 +46,7 @@ public final class CodaHaleMetricsTracker extends MetricsTracker
connectionUsage.update(usageMilleseconds);
}
public static final class Context extends MetricsTracker.Context
public static final class Context extends MetricsContext
{
Timer.Context innerContext;

@ -0,0 +1,57 @@
/*
* Copyright (C) 2014 Brett Wooldridge
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.zaxxer.hikari.metrics;
/**
*
* @author Brett Wooldridge
*/
public interface IMetricsTracker
{
/**
* This method is called when a connection request starts. The {@#MetricsContext.stop()}
* method will be called at the completion of the connection request, whether or not an
* exception occurred.
*
* @param startTime the timestamp of the start time as returned by System.currentTimeMillis()
* @return an instance of MetricsContext
*/
public MetricsContext recordConnectionRequest(long startTime);
/**
* This method is called when a Connection is closed, with the total time in milliseconds
* that the Connection was out of the pool.
*
* @param usageMilleseconds the Connection usage time in milliseconds
*/
public void recordConnectionUsage(long usageMilleseconds);
/**
* A base instance of a MetricsContext. Classes extending this class should exhibit the
* behavior of "starting" a timer upon contruction, and "stopping" the timer when the
* {@#stop()} method is called.
*
* @author Brett Wooldridge
*/
public static class MetricsContext
{
public void stop()
{
// do nothing
}
}
}

@ -0,0 +1,36 @@
/*
* Copyright (C) 2014 Brett Wooldridge
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.zaxxer.hikari.metrics;
import com.zaxxer.hikari.util.PoolUtilities;
/**
*
* @author Brett Wooldridge
*/
public final class MetricsFactory
{
private MetricsFactory()
{
// private contructor
}
public static final IMetricsTracker createMetricsTracker(String metricsClassName, String poolName)
{
return PoolUtilities.createInstance(metricsClassName, IMetricsTracker.class, poolName);
}
}

@ -22,19 +22,19 @@ package com.zaxxer.hikari.metrics;
*
* @author Brett Wooldridge
*/
public class MetricsTracker
public class MetricsTracker implements IMetricsTracker
{
public static final Context NO_CONTEXT = new Context();
public static final MetricsContext NO_CONTEXT = new MetricsContext();
public static class Context
public MetricsTracker()
{
public void stop()
{
// do nothing
}
}
public Context recordConnectionRequest(long start)
public MetricsTracker(String poolName)
{
}
public MetricsContext recordConnectionRequest(long requestTime)
{
return NO_CONTEXT;
}

@ -16,6 +16,14 @@
package com.zaxxer.hikari.pool;
import static com.zaxxer.hikari.util.PoolUtilities.IS_JAVA7;
import static com.zaxxer.hikari.util.PoolUtilities.createInstance;
import static com.zaxxer.hikari.util.PoolUtilities.createThreadPoolExecutor;
import static com.zaxxer.hikari.util.PoolUtilities.elapsedTimeMs;
import static com.zaxxer.hikari.util.PoolUtilities.executeSqlAutoCommit;
import static com.zaxxer.hikari.util.PoolUtilities.quietlyCloseConnection;
import static com.zaxxer.hikari.util.PoolUtilities.quietlySleep;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
@ -34,9 +42,10 @@ import org.slf4j.LoggerFactory;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.IConnectionCustomizer;
import com.zaxxer.hikari.metrics.CodaHaleMetricsTracker;
import com.zaxxer.hikari.metrics.IMetricsTracker;
import com.zaxxer.hikari.metrics.IMetricsTracker.MetricsContext;
import com.zaxxer.hikari.metrics.MetricsFactory;
import com.zaxxer.hikari.metrics.MetricsTracker;
import com.zaxxer.hikari.metrics.MetricsTracker.Context;
import com.zaxxer.hikari.proxy.IHikariConnectionProxy;
import com.zaxxer.hikari.proxy.ProxyFactory;
import com.zaxxer.hikari.util.ConcurrentBag;
@ -44,14 +53,6 @@ import com.zaxxer.hikari.util.ConcurrentBag.IBagStateListener;
import com.zaxxer.hikari.util.DriverDataSource;
import com.zaxxer.hikari.util.PropertyBeanSetter;
import static com.zaxxer.hikari.util.PoolUtilities.elapsedTimeMs;
import static com.zaxxer.hikari.util.PoolUtilities.createInstance;
import static com.zaxxer.hikari.util.PoolUtilities.createThreadPoolExecutor;
import static com.zaxxer.hikari.util.PoolUtilities.executeSqlAutoCommit;
import static com.zaxxer.hikari.util.PoolUtilities.quietlySleep;
import static com.zaxxer.hikari.util.PoolUtilities.quietlyCloseConnection;
import static com.zaxxer.hikari.util.PoolUtilities.IS_JAVA7;
/**
* This is the primary connection pool class that provides the basic
* pooling behavior for HikariCP.
@ -68,7 +69,11 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
private final HikariConfig configuration;
private final ConcurrentBag<IHikariConnectionProxy> connectionBag;
private final ThreadPoolExecutor addConnectionExecutor;
private final MetricsTracker metricsTracker;
private final IMetricsTracker metricsTracker;
private final AtomicReference<Throwable> lastConnectionFailure;
private final AtomicInteger totalConnections;
private final Timer houseKeepingTimer;
private final boolean isAutoCommit;
private final boolean isIsolateInternalQueries;
@ -77,9 +82,6 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
private final boolean isRegisteredMbeans;
private final boolean isJdbc4ConnectionTest;
private final long leakDetectionThreshold;
private final AtomicReference<Throwable> lastConnectionFailure;
private final AtomicInteger totalConnections;
private final Timer houseKeepingTimer;
private final String catalog;
private final String username;
private final String password;
@ -127,7 +129,7 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
this.leakDetectionThreshold = configuration.getLeakDetectionThreshold();
this.transactionIsolation = configuration.getTransactionIsolation();
this.isRecordMetrics = configuration.isRecordMetrics();
this.metricsTracker = (isRecordMetrics ? new CodaHaleMetricsTracker(configuration.getPoolName()) : new MetricsTracker());
this.metricsTracker = MetricsFactory.createMetricsTracker((isRecordMetrics ? configuration.getMetricsTrackerClassName() : "com.zaxxer.hikari.metrics.MetricsTracker"), configuration.getPoolName());
this.dataSource = initializeDataSource();
@ -154,7 +156,7 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
public Connection getConnection() throws SQLException
{
final long start = System.currentTimeMillis();
final Context context = (isRecordMetrics ? metricsTracker.recordConnectionRequest(start) : MetricsTracker.NO_CONTEXT);
final MetricsContext context = (isRecordMetrics ? metricsTracker.recordConnectionRequest(start) : MetricsTracker.NO_CONTEXT);
long timeout = connectionTimeout;
try
@ -433,7 +435,8 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
{
try
{
timeoutMs = Math.max(1000L, timeoutMs);
final boolean timeoutEnabled = (configuration.getConnectionTimeout() != Integer.MAX_VALUE);
timeoutMs = timeoutEnabled ? Math.max(1000L, timeoutMs) : 0;
if (isJdbc4ConnectionTest)
{
@ -443,11 +446,9 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
Statement statement = connection.createStatement();
try
{
if (configuration.getConnectionTimeout() < Integer.MAX_VALUE)
{
statement.setQueryTimeout((int) TimeUnit.MILLISECONDS.toSeconds(timeoutMs));
}
statement.setQueryTimeout((int) TimeUnit.MILLISECONDS.toSeconds(timeoutMs));
statement.executeQuery(configuration.getConnectionTestQuery());
return true;
}
finally
{
@ -457,8 +458,6 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
connection.rollback();
}
}
return true;
}
catch (SQLException e)
{
@ -540,16 +539,9 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
String dsClassName = configuration.getDataSourceClassName();
if (configuration.getDataSource() == null && dsClassName != null)
{
try
{
DataSource dataSource = createInstance(dsClassName, DataSource.class);
PropertyBeanSetter.setTargetFromProperties(dataSource, configuration.getDataSourceProperties());
return dataSource;
}
catch (Exception e)
{
throw new RuntimeException("Could not create datasource instance: " + dsClassName, e);
}
DataSource dataSource = createInstance(dsClassName, DataSource.class);
PropertyBeanSetter.setTargetFromProperties(dataSource, configuration.getDataSourceProperties());
return dataSource;
}
else if (configuration.getJdbcUrl() != null)
{
@ -563,14 +555,7 @@ public final class HikariPool implements HikariPoolMBean, IBagStateListener
{
if (configuration.getConnectionCustomizerClassName() != null)
{
try
{
return createInstance(configuration.getConnectionCustomizerClassName(), IConnectionCustomizer.class);
}
catch (Exception e)
{
LOGGER.error("Connection customizer could not be created", e);
}
return createInstance(configuration.getConnectionCustomizerClassName(), IConnectionCustomizer.class);
}
return configuration.getConnectionCustomizer();

@ -58,7 +58,7 @@ public abstract class ConnectionProxy implements IHikariConnectionProxy
private boolean forceClose;
private boolean isAutoCommitDirty;
private boolean isCatalogDirty;
private volatile boolean isClosed;
private boolean isClosed;
private boolean isReadOnlyDirty;
private boolean isTransactionIsolationDirty;
private volatile long lastAccess;

@ -1,5 +1,6 @@
package com.zaxxer.hikari.util;
import java.lang.reflect.Constructor;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
@ -90,7 +91,7 @@ public final class PoolUtilities
}
@SuppressWarnings("unchecked")
public static <T> T createInstance(String className, Class<T> clazz)
public static <T> T createInstance(String className, Class<T> clazz, Object...args)
{
if (className == null)
{
@ -100,6 +101,19 @@ public final class PoolUtilities
try
{
Class<?> loaded = PoolUtilities.class.getClassLoader().loadClass(className);
Class<?>[] argClasses = new Class<?>[args.length];
for (int i = 0; i < args.length; i++)
{
argClasses[i] = args[i].getClass();
}
if (args.length > 0)
{
Constructor<?> constructor = loaded.getConstructor(argClasses);
return (T) constructor.newInstance(args);
}
return (T) loaded.newInstance();
}
catch (Exception e)

Loading…
Cancel
Save