问题
After upgrading to hibernate 4.2.4 from 3.6 database connections are not returned to pool after initialisation of lazy collection. As a result connection pool is exhausted very quickly when number of users exceeds number of connections in the pool. Similar symptoms are described in HHH-4808 but we haven't observed these problems in Hibernate 3.1-3.6
Relevant settings:
hibernate.connection.autocommit=true
hibernate.connection.release_mode=after_transaction
After collection is initialized there is no open transaction. So according to setting connection has to be released.
In hibernate 3.6 connection was released (through indirect call to ConnectionManager.aggresiveRelease() from OneToManyLoader). This is very critical change for our usage scenario. Was this change intentional? Is it possible to activate old behaviour through some combination of settings?
回答1:
We found a workaround. Does anybody see drawbacks?
EventListenerRegistry registry = ((SessionFactoryImpl)sessionFactory).getServiceRegistry().getService(EventListenerRegistry.class);
registry.appendListeners(EventType.INIT_COLLECTION, new InitializeCollectionEventListener());
public class InitializeCollectionEventListener implements InitializeCollectionEventListener{
DefaultInitializeCollectionEventListener defaultListener;
InitializeCollectionEventListener(){
defaultListener = new DefaultInitializeCollectionEventListener();
}
public void onInitializeCollection(InitializeCollectionEvent pEvent) throws HibernateException {
defaultListener.onInitializeCollection(pEvent);
SessionImpl si = (SessionImpl) pEvent.getSession();
if (!si.isTransactionInProgress() && !si.isClosed() && si.isConnected() &&
si.getConnectionReleaseMode().equals(ConnectionReleaseMode.AFTER_TRANSACTION)){
si.getTransactionCoordinator().getJdbcCoordinator().getLogicalConnection().aggressiveRelease();
}
}
}
来源:https://stackoverflow.com/questions/19140609/hibernate-connections-are-not-released-after-lazy-collection-initialization