Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HHH-10943 - Driver Manager Connection Pool should close leaked connec… #1470

Merged
merged 1 commit into from Jul 12, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -52,7 +52,6 @@ public class DriverManagerConnectionProviderImpl

private boolean active = true;

private ConnectionCreator connectionCreator;
private ScheduledExecutorService executorService;
private PooledConnections pool;

Expand All @@ -70,7 +69,6 @@ public void injectServices(ServiceRegistryImplementor serviceRegistry) {
public void configure(Map configurationValues) {
log.usingHibernateBuiltInConnectionPool();

connectionCreator = buildCreator( configurationValues );
pool = buildPool( configurationValues );

final long validationInterval = ConfigurationHelper.getLong( VALIDATION_INTERVAL, configurationValues, 30 );
Expand Down Expand Up @@ -99,6 +97,7 @@ private PooledConnections buildPool(Map configurationValues) {
final int maxSize = ConfigurationHelper.getInt( AvailableSettings.POOL_SIZE, configurationValues, 20 );
final int initialSize = ConfigurationHelper.getInt( INITIAL_SIZE, configurationValues, minSize );

ConnectionCreator connectionCreator = buildCreator( configurationValues );
PooledConnections.Builder pooledConnectionBuilder = new PooledConnections.Builder(
connectionCreator,
autoCommit
Expand Down Expand Up @@ -184,11 +183,7 @@ public Connection getConnection() throws SQLException {
throw new HibernateException( "Connection pool is no longer active" );
}

Connection conn = pool.poll();
if ( conn == null ) {
conn = connectionCreator.createConnection();
}
return conn;
return pool.poll();
}

@Override
Expand Down Expand Up @@ -232,7 +227,7 @@ public void stop() {
return;
}

log.cleaningUpConnectionPool( connectionCreator.getUrl() );
log.cleaningUpConnectionPool( pool.getUrl() );

active = false;

Expand Down
Expand Up @@ -10,6 +10,7 @@
import java.sql.SQLException;
import java.util.concurrent.ConcurrentLinkedQueue;

import org.hibernate.HibernateException;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;

Expand All @@ -18,7 +19,8 @@
*/
public class PooledConnections {

private ConcurrentLinkedQueue<Connection> connections = new ConcurrentLinkedQueue<Connection>();
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 );

Expand Down Expand Up @@ -65,35 +67,50 @@ else if ( size > maxSize ) {
public void add(Connection conn) throws SQLException {
conn.setAutoCommit( true );
conn.clearWarnings();
connections.offer( conn );
availableConnections.offer( conn );
}

public Connection poll() throws SQLException {
Connection conn = connections.poll();
Connection conn = availableConnections.poll();
if ( conn == null ) {
return 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 {
for ( Connection connection : connections ) {
connection.close();
try {
int allocationCount = allConnections.size() - availableConnections.size();
if(allocationCount > 0) {
log.error( "Collection leak detected: there are " + allocationCount + " unclosed connections upon shutting down pool " + getUrl());
}
}
finally {
for ( Connection connection : allConnections ) {
connection.close();
}
}
}

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

protected void removeConnections(int numberToBeRemoved) {
for ( int i = 0; i < numberToBeRemoved; i++ ) {
Connection connection = connections.poll();
Connection connection = availableConnections.poll();
try {
if ( connection != null ) {
connection.close();
}
allConnections.remove( connection );
}
catch (SQLException e) {
log.unableToCloseConnection( e );
Expand All @@ -103,10 +120,16 @@ protected void removeConnections(int numberToBeRemoved) {

protected void addConnections(int numberOfConnections) {
for ( int i = 0; i < numberOfConnections; i++ ) {
connections.add( connectionCreator.createConnection() );
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;
Expand Down
Expand Up @@ -521,5 +521,9 @@ public void testCurrentSessionWithScroll() throws Exception {
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit();
}

protected boolean rebuildSessionFactoryOnError() {
return false;
}

}

Expand Up @@ -23,7 +23,7 @@
<property name="connection.password"></property>

<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<property name="connection.pool_size">5</property>

<!-- SQL dialect -->
<property name="dialect">
Expand Down
Expand Up @@ -23,7 +23,7 @@
<property name="connection.password"></property>

<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<property name="connection.pool_size">5</property>

<!-- SQL dialect -->
<property name="dialect">
Expand Down
Expand Up @@ -148,7 +148,12 @@ public <T> T unwrap(Class<T> unwrapType) {

private void delist(Connection connection) {
// todo : verify the incoming connection is the currently enlisted one?
TestingJtaPlatformImpl.synchronizationRegistry().putResource( CONNECTION_KEY, null );
try {
TestingJtaPlatformImpl.synchronizationRegistry().putResource( CONNECTION_KEY, null );
}
catch ( Exception e ) {
System.err.println( "!!!Error trying to reset synchronization registry!!!" );
}
try {
delegate.closeConnection( connection );
}
Expand Down