在延迟收集初始化后,Hibernate连接不会被释放 [英] Hibernate connections are not released after lazy collection initialization

查看:214
本文介绍了在延迟收集初始化后,Hibernate连接不会被释放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从3.6升级到hibernate 4.2.4后,数据库连接在初始化延迟收集后不会返回到池。因此,当用户数超过池中的连接数时,连接池会非常快速地耗尽。
类似的症状在 HHH-4808 中描述,但我们没有观察到这些Hibernate 3.1-3.6中的问题



相关设置:

  hibernate。 connection.autocommit = true 
hibernate.connection.release_mode = after_transaction

在初始化集合后没有公开交易。因此根据设置连接必须被释放。



在hibernate 3.6连接被释放后(通过从OneToManyLoader间接调用ConnectionManager.aggresiveRelease())。
这对我们的使用场景非常重要。这种变化是故意的吗?是否可以通过一些设置组合来激活旧行为?

解决方案

我们找到了解决方法。是否有人看到缺点?

  EventListenerRegistry注册表=((SessionFactoryImpl)sessionFactory).getServiceRegistry()。getService(EventListenerRegistry 。类); 
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(); ()&&!si.isClosed()&& si.isConnected()&&
si.getConnectionReleaseMode()。equals(ConnectionReleaseMode.AFTER_TRANSACTION )){
si.getTransactionCoordinator()。getJdbcCoordinator()。getLogicalConnection()。aggressiveRelease();
}
}

}


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?

解决方案

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(); 
        }
    }

}

这篇关于在延迟收集初始化后,Hibernate连接不会被释放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆