getSession()这个方法本身其实返回的是与当前事务绑定的Session对象,在HibernateDaoSupport中使
用,HibernateDaoSupport本身是不负责对这个Session对象进行关闭的,所以在其中有一个对应的releaseSession()
方法,用于关闭Session。
但是一般使用Spring时,我们会采用HibernateTransactionManager进行事务管理,把事务配置在Service层。
此时,它会帮助我们关闭与当前事务绑定的Session对象,这个可以参照HibernateTransactionManager类中的
doCleanupAfterCompletion方法,它是一个抽象方法的实现。再追溯上去,会发现,在事务commit或者rollback的时候,
会有一段finally代码,专门调用执行该方法的代码:
-
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());
-
}
-
}
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());的调用:
-
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;
-
}
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帮你完成。
分享到:
相关推荐
在一个线程内进行多次操作时,`getSession()`每次都会创建一个新的Session,可能导致数据库连接数过多,从而超出数据库允许的最大连接数。而`HibernateTemplate`则可以更好地控制和管理Session,避免这个问题。 ...
原因是`getSession()`会在每个操作时创建新的Session,如果在一个线程中有大量的并发操作,这可能导致数据库连接数过多,超出数据库允许的最大连接数,从而引发性能问题。而`getHibernateTemplate()`则能更好地管理...
c3p0提供了许多配置选项,如最小连接数、最大连接数、检查连接的空闲时间等,可以根据实际需求调整以优化性能。 整合Spring和Hibernate时,我们需要在Spring的配置文件中定义数据源,这里就是使用c3p0作为数据源。...
在数据库处理方面,不需要在数据层借助存储过程及数据库服务器端函数封装过多的业务逻辑,因此数据库系统采用相对精巧的MySQL[6]。 该在线博客系统服务器端如果需要布置到其他主机上,则该主机必备条件如下: 1. ...
- **Spring**:作为依赖注入和面向切面编程的容器,管理应用程序的生命周期,同时也是连接其他两个框架的桥梁。 #### 三、分页方案设计 分页显示是Web开发中常见的需求之一,尤其在数据量较大时尤为重要。为了实现...
public Student doInHibernate(Session session) throws HibernateException { // ... 查询逻辑 ... } }); } } ``` 二、Spring整合Struts 1. **配置Struts的Action**:在Struts的配置文件(struts-config.xml)...
LobHandler必须注入到Hibernate会话工厂sessionFactory中,因为sessionFactory负责产生与数据库交互的Session。LobHandler的配置如代码 5所示: 代码 5 Lob字段的处理句柄配置 1. 2. … 3. 4. class="org....