程序代码
public class DaoReal extends HibernateDaoSupport implements Dao {
public List<user> getAll() {
Session s = super.getSession();
try {
return s.createQuery("from User").list();
} finally {
s.close();
}
}
}
问题:(利用session.createQuery(...)方法的隐患)
上面的例子中隐藏了一个问题,数据库连接并没有被关闭,在我们的印象中这件事似乎应该是Spring的。程序执行后,好像也没有什么问题,但是连续执行该语句n次(n<=最大连接数,如果没有指定最大连接数,那么默认为10次)后,系统处于等待状态,不会继续执行了,控制台上并没有输出任何信息。打开log文件,发现系统抛出java.lang.IllegalStateException: Pool not open的异常,无法打开连接。这说明系统连接池中所有的连接都在使用中。 执行n遍后依然停止响应。问题出在哪里呢?其实Spring的Session总是与某个线程绑定的,而这个线程往往就是承载Servlet或Jsp的那个线程,也就是说,它的生命周期scope是request的。在上面的例子中,我们利用getSession强制获得了Hibernate的 Session,这个Session可能是当前事务中之前使用过的,或者可能是一个新的,并不在当前事务中,Spring只对当前事务中的Session 进行关闭。
请教大家有什么解决办法没? 还是我提的问题是错误的?谢谢大家?
问题补充
回楼上:
用到了hibernate+spring的话,一般我们直接用getHibernateTemplate().find("from User")这类型的查询。 单是现在我项目里面程序用到这个类型的:
Session s = super.getSession();
try {
return s.createQuery("from User").list();
} finally {
s.close();
} 我们测试中好像发现了这个session完全不能关闭好像。是不是这么回事??
public class DaoReal extends HibernateDaoSupport implements Dao {
public List<user> getAll() {
Session s = super.getSession();
try {
return s.createQuery("from User").list();
} finally {
s.close();
}
}
}
问题:(利用session.createQuery(...)方法的隐患)
上面的例子中隐藏了一个问题,数据库连接并没有被关闭,在我们的印象中这件事似乎应该是Spring的。程序执行后,好像也没有什么问题,但是连续执行该语句n次(n<=最大连接数,如果没有指定最大连接数,那么默认为10次)后,系统处于等待状态,不会继续执行了,控制台上并没有输出任何信息。打开log文件,发现系统抛出java.lang.IllegalStateException: Pool not open的异常,无法打开连接。这说明系统连接池中所有的连接都在使用中。 执行n遍后依然停止响应。问题出在哪里呢?其实Spring的Session总是与某个线程绑定的,而这个线程往往就是承载Servlet或Jsp的那个线程,也就是说,它的生命周期scope是request的。在上面的例子中,我们利用getSession强制获得了Hibernate的 Session,这个Session可能是当前事务中之前使用过的,或者可能是一个新的,并不在当前事务中,Spring只对当前事务中的Session 进行关闭。
请教大家有什么解决办法没? 还是我提的问题是错误的?谢谢大家?
问题补充
回楼上:
用到了hibernate+spring的话,一般我们直接用getHibernateTemplate().find("from User")这类型的查询。 单是现在我项目里面程序用到这个类型的:
Session s = super.getSession();
try {
return s.createQuery("from User").list();
} finally {
s.close();
} 我们测试中好像发现了这个session完全不能关闭好像。是不是这么回事??
HibernateSessionFactory.closeSession()
就不用你自己手动的去控制session了,你直接通过
this.getHibernateTemplete().find(hql);进行操作就好啦。
其他的交给spring就OK,要不然你使用spring的意义好像不大吧
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!-- 配置事务的特性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="del*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="*" read-only="true"/>
</tx:attributes>
</tx:advice>
<!-- 配置那些类的方法进行事务管理 --> <aop:config>
<aop:pointcut id="allManagerMethod" expression="execution (* com.song.services.impl.*.*(..) )"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod"/>
</aop:config>