`
wobuxiaole
  • 浏览: 41287 次
  • 来自: ...
社区版块
存档分类
最新评论

HibernateDaoSupport Session关闭不了,连接数过多。

阅读更多

getSession()这个方法本身其实返回的是与当前事务绑定的Session对象,在HibernateDaoSupport中使 用,HibernateDaoSupport本身是不负责对这个Session对象进行关闭的,所以在其中有一个对应的releaseSession() 方法,用于关闭Session。

但是一般使用Spring时,我们会采用HibernateTransactionManager进行事务管理,把事务配置在Service层。 此时,它会帮助我们关闭与当前事务绑定的Session对象,这个可以参照HibernateTransactionManager类中的 doCleanupAfterCompletion方法,它是一个抽象方法的实现。再追溯上去,会发现,在事务commit或者rollback的时候, 会有一段finally代码,专门调用执行该方法的代码:

Java代码
  1. finally  {  
  2.             cleanupAfterCompletion(status);  
  3.         }  
  4.   
  5.     private   void  cleanupAfterCompletion(DefaultTransactionStatus status) {  
  6.         status.setCompleted();  
  7.         if  (status.isNewSynchronization()) {  
  8.             TransactionSynchronizationManager.clearSynchronization();  
  9.             TransactionSynchronizationManager.setCurrentTransactionName(null );  
  10.             TransactionSynchronizationManager.setCurrentTransactionReadOnly(false );  
  11.             if  (status.isNewTransaction()) {  
  12.                 TransactionSynchronizationManager.setActualTransactionActive(false );  
  13.             }  
  14.         }  
  15.         if  (status.isNewTransaction()) {  
  16.             doCleanupAfterCompletion(status.getTransaction());  
  17.         }  
  18.         if  (status.getSuspendedResources() !=  null ) {  
  19.             if  (status.isDebug()) {  
  20.                 logger.debug("Resuming suspended transaction" );  
  21.             }  
  22.             resume(status.getTransaction(), (SuspendedResourcesHolder) status.getSuspendedResources());  
  23.         }  
  24.     }  
finally {
			cleanupAfterCompletion(status);
		}

	private void cleanupAfterCompletion(DefaultTransactionStatus status) {
		status.setCompleted();
		if (status.isNewSynchronization()) {
			TransactionSynchronizationManager.clearSynchronization();
			TransactionSynchronizationManager.setCurrentTransactionName(null);
			TransactionSynchronizationManager.setCurrentTransactionReadOnly(false);
			if (status.isNewTransaction()) {
				TransactionSynchronizationManager.setActualTransactionActive(false);
			}
		}
		if (status.isNewTransaction()) {
			doCleanupAfterCompletion(status.getTransaction());
		}
		if (status.getSuspendedResources() != null) {
			if (status.isDebug()) {
				logger.debug("Resuming suspended transaction");
			}
			resume(status.getTransaction(), (SuspendedResourcesHolder) status.getSuspendedResources());
		}
	}



故而,只要参与了事务,HibernateTransactionManager会帮你正确关闭Session。

不过很多的web应用都会采用OpenSessionInView模式,也就是Session会被保持到View层。同样经过 HibernateTransactionManager,为什么使用了OpenSessionInView模式以后,Session就不会被关闭呢?这 是由于在获取当前线程绑定事务的时候,有一个判断,如果存在当前线程绑定的Session,会把当前事务对象的newSessionHolder值设置成 false,从而跳过上面的代码中doCleanupAfterCompletion(status.getTransaction());的调用:

Java代码
  1. protected  Object doGetTransaction() {  
  2.         HibernateTransactionObject txObject = new  HibernateTransactionObject();  
  3.         txObject.setSavepointAllowed(isNestedTransactionAllowed());  
  4.   
  5.         if  (TransactionSynchronizationManager.hasResource(getSessionFactory())) {  
  6.             SessionHolder sessionHolder =  
  7.                     (SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory());  
  8.             if  (logger.isDebugEnabled()) {  
  9.                 logger.debug("Found thread-bound Session ["  +  
  10.                         SessionFactoryUtils.toString(sessionHolder.getSession()) + "] for Hibernate transaction" );  
  11.             }  
  12.             txObject.setSessionHolder(sessionHolder, false );  
  13.             if  (getDataSource() !=  null ) {  
  14.                 ConnectionHolder conHolder = (ConnectionHolder)  
  15.                         TransactionSynchronizationManager.getResource(getDataSource());  
  16.                 txObject.setConnectionHolder(conHolder);  
  17.             }  
  18.         }  
  19.   
  20.         return  txObject;  
  21.     }  
protected Object doGetTransaction() {
		HibernateTransactionObject txObject = new HibernateTransactionObject();
		txObject.setSavepointAllowed(isNestedTransactionAllowed());

		if (TransactionSynchronizationManager.hasResource(getSessionFactory())) {
			SessionHolder sessionHolder =
					(SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory());
			if (logger.isDebugEnabled()) {
				logger.debug("Found thread-bound Session [" +
						SessionFactoryUtils.toString(sessionHolder.getSession()) + "] for Hibernate transaction");
			}
			txObject.setSessionHolder(sessionHolder, false);
			if (getDataSource() != null) {
				ConnectionHolder conHolder = (ConnectionHolder)
						TransactionSynchronizationManager.getResource(getDataSource());
				txObject.setConnectionHolder(conHolder);
			}
		}

		return txObject;
	}



综合一下,只要使用Spring的TransactionManager来管理事务,就可以放心在HibernateDaoSupport中使用getSession(),释放的工作会有Spring帮你完成。

分享到:
评论

相关推荐

    HibernateDaoSupport的使用

    通过`getHibernateTemplate()`方法,我们可以获取到一个预配置好的HibernateTemplate对象,它会自动处理Session的打开、关闭和事务提交/回滚。 3. HibernateTemplate的使用:HibernateTemplate是Spring提供的一个...

    HibernateDaoSupport 与@Autowired

    通过继承`HibernateDaoSupport`,开发者可以轻松地获得SessionFactory的引用,而无需手动管理Session和Transaction。`HibernateDaoSupport`的核心方法包括: 1. `setSessionFactory(SessionFactory sessionFactory)...

    hibernateDaoSupport类的运用实例

    由于`hibernateDaoSupport`已经提供了获取`Session`的方法,因此我们不再需要手动打开`SessionFactory`来获取`Session`: ```java Session se = this.getSession(); ``` ##### 3. 执行HQL查询 在执行HQL查询时,...

    spring 理解文件HibernateDaoSupport

    根据给定的信息,我们可以深入探讨Spring框架中与Hibernate集成的相关知识点,特别关注“HibernateDaoSupport”类及其在Spring环境中的应用。以下是对标题、描述以及部分文件内容的详细解析: ### 一、Spring与...

    HibernateDaoSupport 源码

    Spring hibernate3. HibernateDaoSupport 源码

    HibernateDaoSupport二次封装组件,快速统计和查询,修改

    首先,`HibernateDaoSupport`提供了对`SessionFactory`的管理,开发者可以通过它获取到`Session`对象,执行数据库操作。通过继承`HibernateDaoSupport`,我们可以轻松地实现对数据库的基本CRUD(创建、读取、更新、...

    HibernateDaoSupport 类的jar

    HibernateDaoSupport 类的jar HibernateDao 的jar

    SSH整合(其中dao用extends HibernateDaoSupport方式)总结【图解】

    SSH整合(其中dao用extends HibernateDaoSupport方式)总结【图解】

    springboot2.0多数据源集成hibernate配置hibernateDaoSupport示例

    在DAO层,我们不使用JPA,而是使用`HibernateDaoSupport`。`HibernateDaoSupport`是Spring提供的一类辅助类,它提供了与Hibernate SessionFactory的连接,简化了Hibernate的使用。首先,我们需要创建一个基础的DAO...

    HibernateDaoSupport分页.

    ### HibernateDaoSupport 分页实现详解 #### 一、概述 在Java开发中,尤其是在Web应用领域,对数据库的高效查询及数据展示是非常重要的一个环节。其中分页查询是提高用户体验和减轻服务器压力的一种常见手段。...

    HibernateDaoSupport.docx

    【HibernateDaoSupport】是Spring框架中的一个抽象类,主要用于简化Hibernate的数据访问操作,它为DAO层提供了方便的事务管理和Session管理。这个类是Spring与Hibernate集成的重要组件,尤其对于初学者来说,理解其...

    hibernateTemplate和HibernateDaoSupport

    HibernateTemplate 是 Spring 提供的一个模板类,它封装了对 Hibernate Session 的操作,避免了直接与 Session 进行交互时出现的事务管理、异常处理等问题。HibernateTemplate 提供了一组丰富的静态方法,涵盖了大...

    HibernateDaoSupport与JdbcDaoSupport

    - **简介**:当项目不需要对象关系映射(ORM)功能或不希望引入额外框架时,可以选择使用`JdbcDaoSupport`。该类提供了一个`jdbcTemplate`属性,通过它可以执行原生SQL语句,实现对数据库的操作。 - **示例代码**:...

    hibernateDaoSupport.txt

    同时,这种方式还支持不同的Hibernate版本,如从Hibernate 2升级到Hibernate 3或更高版本时,只需要修改`HibernateDaoSupport`的实现即可,而不需要修改大量的具体DAO类。 #### 四、示例代码 下面是一个简单的示例...

    HibernateTemplate及generator用法.doc

    在一个线程内进行多次操作时,`getSession()`每次都会创建一个新的Session,可能导致数据库连接数过多,从而超出数据库允许的最大连接数。而`HibernateTemplate`则可以更好地控制和管理Session,避免这个问题。 ...

    JSP 开发之 releaseSession的实例详解

    在JSP开发中,`releaseSession`是一个关键的方法,用于管理Hibernate Session的生命周期,尤其是在处理大量并发请求时,正确地释放Session资源对于防止连接池耗尽至关重要。在给出的实例中,开发者遇到了一个问题,...

    spring-boot 集成hibernate

    2. **配置Druid**: 在`application.properties`或`application.yml`中配置Druid的相关参数,包括数据源的基本信息、最大最小连接数、超时时间等。 ```properties spring.datasource.type=...

    JPA(hibernate) Dao 和 DaoSupport

    在Spring框架中,`DaoSupport`是一个抽象类,为DAO实现提供了一些基础支持,比如初始化和关闭数据库资源。继承自`DaoSupport`的DAO类可以利用其提供的便利方法,如`getJdbcTemplate()`或`getHibernateTemplate()`,...

    重写Spring的HibernateDaoSupport 简化Dao层写法

    NULL 博文链接:https://wxinpeng.iteye.com/blog/1162157

    HibernateTemplate及generator用法.docx

    原因是`getSession()`会在每个操作时创建新的Session,如果在一个线程中有大量的并发操作,这可能导致数据库连接数过多,超出数据库允许的最大连接数,从而引发性能问题。而`getHibernateTemplate()`则能更好地管理...

Global site tag (gtag.js) - Google Analytics