Ultimate JDBC Connection Pool
—
Runtime monitoring and management capabilities through JMX beans, providing pool statistics and runtime configuration changes.
Monitor real-time pool statistics through the HikariPoolMXBean interface.
/**
* JMX management bean interface for pool monitoring and control
*/
public interface HikariPoolMXBean {
/**
* Get the number of currently idle connections in the pool
* @return the number of idle connections
*/
int getIdleConnections();
/**
* Get the number of currently active (in-use) connections
* @return the number of active connections
*/
int getActiveConnections();
/**
* Get the total number of connections in the pool (idle + active)
* @return the total number of connections
*/
int getTotalConnections();
/**
* Get the number of threads currently awaiting a connection from the pool
* @return the number of threads awaiting connection
*/
int getThreadsAwaitingConnection();
}Usage Examples:
// Access through HikariDataSource
HikariDataSource dataSource = new HikariDataSource(config);
HikariPoolMXBean poolBean = dataSource.getHikariPoolMXBean();
if (poolBean != null) {
// Monitor pool health
int active = poolBean.getActiveConnections();
int idle = poolBean.getIdleConnections();
int total = poolBean.getTotalConnections();
int waiting = poolBean.getThreadsAwaitingConnection();
System.out.println("Pool Statistics:");
System.out.println(" Active: " + active);
System.out.println(" Idle: " + idle);
System.out.println(" Total: " + total);
System.out.println(" Waiting threads: " + waiting);
// Check pool utilization
double utilization = (double) active / total * 100;
if (utilization > 80) {
System.out.println("High pool utilization: " + utilization + "%");
}
}Control pool behavior through management operations.
/**
* Perform a "soft" eviction of idle connections. Connections that are currently in use
* will not be evicted, only idle connections will be removed from the pool.
*/
void softEvictConnections();
/**
* Suspend allocation of connections from the pool. All callers to getConnection()
* will block indefinitely until resumePool() is called.
*/
void suspendPool();
/**
* Resume allocation of connections from the pool after a call to suspendPool().
*/
void resumePool();Usage Examples:
HikariPoolMXBean poolBean = dataSource.getHikariPoolMXBean();
// Evict idle connections (useful for maintenance)
poolBean.softEvictConnections();
// Suspend pool for maintenance
poolBean.suspendPool();
try {
// Perform database maintenance operations
performDatabaseMaintenance();
} finally {
// Always resume the pool
poolBean.resumePool();
}
// Graceful pool drain for shutdown
poolBean.suspendPool();
// Wait for active connections to finish
while (poolBean.getActiveConnections() > 0) {
Thread.sleep(100);
}
poolBean.softEvictConnections();Modify pool configuration at runtime through the HikariConfigMXBean interface.
/**
* JMX management bean interface for runtime configuration changes
*/
public interface HikariConfigMXBean {
/**
* Get/set the maximum number of milliseconds that a client will wait for a connection from the pool
*/
long getConnectionTimeout();
void setConnectionTimeout(long connectionTimeoutMs);
/**
* Get/set the maximum number of milliseconds that the pool will wait for a connection to be validated
*/
long getValidationTimeout();
void setValidationTimeout(long validationTimeoutMs);
/**
* Get/set the maximum amount of time that a connection is allowed to sit idle in the pool
*/
long getIdleTimeout();
void setIdleTimeout(long idleTimeoutMs);
/**
* Get/set the amount of time that a connection can be out of the pool before leak detection triggers
*/
long getLeakDetectionThreshold();
void setLeakDetectionThreshold(long leakDetectionThresholdMs);
/**
* Get/set the maximum lifetime of a connection in the pool
*/
long getMaxLifetime();
void setMaxLifetime(long maxLifetimeMs);
/**
* Get/set the minimum number of idle connections that HikariCP tries to maintain in the pool
*/
int getMinimumIdle();
void setMinimumIdle(int minIdle);
/**
* Get/set the maximum size that the pool is allowed to reach
*/
int getMaximumPoolSize();
void setMaximumPoolSize(int maxPoolSize);
/**
* Set the password used for authentication. Changing this at runtime will apply to new connections only.
* Altering this at runtime only works for DataSource-based connections, not Driver-class or JDBC URL-based connections.
*/
void setPassword(String password);
/**
* Set the username used for authentication. Changing this at runtime will apply to new connections only.
* Altering this at runtime only works for DataSource-based connections, not Driver-class or JDBC URL-based connections.
*/
void setUsername(String username);
/**
* Get the name of the connection pool
*/
String getPoolName();
}Usage Examples:
HikariConfigMXBean configBean = dataSource.getHikariConfigMXBean();
// Adjust pool size based on load
int currentLoad = getCurrentSystemLoad();
if (currentLoad > 80) {
// Increase pool size during high load
configBean.setMaximumPoolSize(30);
configBean.setMinimumIdle(10);
} else if (currentLoad < 20) {
// Decrease pool size during low load
configBean.setMaximumPoolSize(10);
configBean.setMinimumIdle(2);
}
// Adjust timeouts for different environments
if (isProductionEnvironment()) {
configBean.setConnectionTimeout(5000); // 5 seconds in production
configBean.setValidationTimeout(1000); // 1 second validation
} else {
configBean.setConnectionTimeout(30000); // 30 seconds in dev/test
configBean.setValidationTimeout(5000); // 5 seconds validation
}
// Enable leak detection in development
if (isDevelopmentEnvironment()) {
configBean.setLeakDetectionThreshold(10000); // 10 seconds
} else {
configBean.setLeakDetectionThreshold(0); // Disabled in production
}
// Update credentials (DataSource-based connections only)
configBean.setUsername("new_user");
configBean.setPassword("new_password");Configure JMX registration and access to management beans.
// In HikariConfig
/**
* Set whether or not JMX Management Beans (MBeans) are registered
* @param register whether to register JMX MBeans
*/
public void setRegisterMbeans(boolean register);
public boolean isRegisterMbeans();
/**
* Set the name of the connection pool. This is primarily used for the MBean
* to uniquely identify the pool configuration.
* @param poolName the name of the connection pool to use
*/
public void setPoolName(String poolName);Usage Examples:
// Enable JMX registration
HikariConfig config = new HikariConfig();
config.setRegisterMbeans(true);
config.setPoolName("MyAppConnectionPool");
config.setJdbcUrl("jdbc:postgresql://localhost:5432/mydb");
HikariDataSource dataSource = new HikariDataSource(config);
// Access via JMX (programmatically)
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
ObjectName poolName = new ObjectName("com.zaxxer.hikari:type=Pool (MyAppConnectionPool)");
ObjectName configName = new ObjectName("com.zaxxer.hikari:type=PoolConfig (MyAppConnectionPool)");
// Get pool statistics via JMX
Integer activeConnections = (Integer) server.getAttribute(poolName, "ActiveConnections");
Integer totalConnections = (Integer) server.getAttribute(poolName, "TotalConnections");
// Modify configuration via JMX
server.setAttribute(configName, new Attribute("MaximumPoolSize", 25));
server.invoke(poolName, "softEvictConnections", null, null);Integrate HikariCP JMX metrics with monitoring systems.
Usage Examples:
// Custom monitoring integration
public class HikariPoolMonitor {
private final HikariPoolMXBean poolBean;
private final HikariConfigMXBean configBean;
private final String poolName;
public HikariPoolMonitor(HikariDataSource dataSource) {
this.poolBean = dataSource.getHikariPoolMXBean();
this.configBean = dataSource.getHikariConfigMXBean();
this.poolName = configBean.getPoolName();
}
public void checkPoolHealth() {
if (poolBean == null) return;
int active = poolBean.getActiveConnections();
int total = poolBean.getTotalConnections();
int waiting = poolBean.getThreadsAwaitingConnection();
// Check for high utilization
double utilization = (double) active / total;
if (utilization > 0.9) {
sendAlert("High pool utilization",
"Pool " + poolName + " is " + (utilization * 100) + "% utilized");
}
// Check for connection starvation
if (waiting > 5) {
sendAlert("Connection starvation",
waiting + " threads waiting for connections in pool " + poolName);
}
// Check for pool exhaustion
if (active >= total && waiting > 0) {
sendAlert("Pool exhausted",
"Pool " + poolName + " has no available connections");
}
}
public Map<String, Object> getMetrics() {
Map<String, Object> metrics = new HashMap<>();
if (poolBean != null) {
metrics.put("active_connections", poolBean.getActiveConnections());
metrics.put("idle_connections", poolBean.getIdleConnections());
metrics.put("total_connections", poolBean.getTotalConnections());
metrics.put("waiting_threads", poolBean.getThreadsAwaitingConnection());
}
metrics.put("max_pool_size", configBean.getMaximumPoolSize());
metrics.put("min_idle", configBean.getMinimumIdle());
metrics.put("connection_timeout", configBean.getConnectionTimeout());
metrics.put("pool_name", configBean.getPoolName());
return metrics;
}
private void sendAlert(String title, String message) {
// Integration with your alerting system
System.err.println("ALERT: " + title + " - " + message);
}
}
// Usage in application
HikariPoolMonitor monitor = new HikariPoolMonitor(dataSource);
// Schedule regular health checks
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(monitor::checkPoolHealth, 0, 30, TimeUnit.SECONDS);Install with Tessl CLI
npx tessl i tessl/maven-com-zaxxer--hikari-cp-java7