Skip to content

Commit

Permalink
HHH-12052 - Move PooledConnections inside DriverManagerConnectionProv…
Browse files Browse the repository at this point in the history
…iderImpl
  • Loading branch information
vladmihalcea committed Oct 23, 2017
1 parent 9ed4438 commit 29fc590
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 164 deletions.
Expand Up @@ -11,6 +11,7 @@
import java.sql.SQLException;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
Expand All @@ -19,6 +20,8 @@
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.log.ConnectionPoolingLogger;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.service.UnknownUnwrapTypeException;
Expand Down Expand Up @@ -254,4 +257,149 @@ protected void finalize() throws Throwable {
}
//CHECKSTYLE:END_ALLOW_FINALIZER

public static class PooledConnections {

private final ConcurrentLinkedQueue<Connection> allConnections = new ConcurrentLinkedQueue<Connection>();
private final ConcurrentLinkedQueue<Connection> availableConnections = new ConcurrentLinkedQueue<Connection>();

private static final CoreMessageLogger log = CoreLogging.messageLogger( DriverManagerConnectionProviderImpl.class );

private final ConnectionCreator connectionCreator;
private final boolean autoCommit;
private final int minSize;
private final int maxSize;

private boolean primed;

private PooledConnections(
Builder builder) {
log.debugf( "Initializing Connection pool with %s Connections", builder.initialSize );
connectionCreator = builder.connectionCreator;
autoCommit = builder.autoCommit;
maxSize = builder.maxSize;
minSize = builder.minSize;
log.hibernateConnectionPoolSize( maxSize, minSize );
addConnections( builder.initialSize );
}

public void validate() {
final int size = size();

if ( !primed && size >= minSize ) {
// IMPL NOTE : the purpose of primed is to allow the pool to lazily reach its
// defined min-size.
log.debug( "Connection pool now considered primed; min-size will be maintained" );
primed = true;
}

if ( size < minSize && primed ) {
int numberToBeAdded = minSize - size;
log.debugf( "Adding %s Connections to the pool", numberToBeAdded );
addConnections( numberToBeAdded );
}
else if ( size > maxSize ) {
int numberToBeRemoved = size - maxSize;
log.debugf( "Removing %s Connections from the pool", numberToBeRemoved );
removeConnections( numberToBeRemoved );
}
}

public void add(Connection conn) throws SQLException {
conn.setAutoCommit( true );
conn.clearWarnings();
availableConnections.offer( conn );
}

public Connection poll() throws SQLException {
Connection conn = availableConnections.poll();
if ( conn == null ) {
synchronized (allConnections) {
if(allConnections.size() < maxSize) {
addConnections( 1 );
return poll();
}
}
throw new HibernateException( "The internal connection pool has reached its maximum size and no connection is currently available!" );
}
conn.setAutoCommit( autoCommit );
return conn;
}

public void close() throws SQLException {
try {
int allocationCount = allConnections.size() - availableConnections.size();
if(allocationCount > 0) {
log.error( "Connection leak detected: there are " + allocationCount + " unclosed connections upon shutting down pool " + getUrl());
}
}
finally {
for ( Connection connection : allConnections ) {
connection.close();
}
}
}

public int size() {
return availableConnections.size();
}

protected void removeConnections(int numberToBeRemoved) {
for ( int i = 0; i < numberToBeRemoved; i++ ) {
Connection connection = availableConnections.poll();
try {
if ( connection != null ) {
connection.close();
}
allConnections.remove( connection );
}
catch (SQLException e) {
log.unableToCloseConnection( e );
}
}
}

protected void addConnections(int numberOfConnections) {
for ( int i = 0; i < numberOfConnections; i++ ) {
Connection connection = connectionCreator.createConnection();
allConnections.add( connection );
availableConnections.add( connection );
}
}

public String getUrl() {
return connectionCreator.getUrl();
}

public static class Builder {
private final ConnectionCreator connectionCreator;
private boolean autoCommit;
private int initialSize = 1;
private int minSize = 1;
private int maxSize = 20;

public Builder(ConnectionCreator connectionCreator, boolean autoCommit) {
this.connectionCreator = connectionCreator;
this.autoCommit = autoCommit;
}

public Builder initialSize(int initialSize) {
this.initialSize = initialSize;
return this;
}

public Builder minSize(int minSize) {
this.minSize = minSize;
return this;
}

public Builder maxSize(int maxSize) {
this.maxSize = maxSize;
return this;
}

public PooledConnections build() {
return new PooledConnections( this );
}
}
}
}

This file was deleted.

0 comments on commit 29fc590

Please sign in to comment.