HHH-12052 - Move PooledConnections inside DriverManagerConnectionProviderImpl
This commit is contained in:
parent
9ed4438f17
commit
29fc5903e3
|
@ -11,6 +11,7 @@ import java.sql.Driver;
|
|||
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;
|
||||
|
@ -19,6 +20,8 @@ import org.hibernate.HibernateException;
|
|||
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;
|
||||
|
@ -254,4 +257,149 @@ public class DriverManagerConnectionProviderImpl
|
|||
}
|
||||
//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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,164 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.engine.jdbc.connections.internal;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
public 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 );
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue