目前还没有真正理解这些设置,想知道是否有人能指出我正确的方向。
我有以下内容,我认为基本上是在说
1:最小池连接数= 5 2:最大池化连接数= 10 3:空闲连接应保持打开多长时间,5秒钟(此时它已关闭并再次可用。
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/testdb" />
<property name="user" value="root" />
<property name="password" value="password" />
<property name="minPoolSize" value="5" />
<property name="maxPoolSize" value="10" />
<property name="maxIdleTime" value="5" />
<property name="maxStatements" value="0" />
</bean>
但是在我的简单小测试应用程序中,只要我在第11个测试表上运行一个简单的选择,其中id = 1 “搜索”,应用程序挂起。
为什么我最多只能连接10个连接,即使我等待超过5秒,为什么没有连接被释放?
- 我班级的片段:
public Object readObject(SessionFactory sessionFactory, String hql, Map<String,Object> args) {
session = this.openHibernateSession(sessionFactory);
Query query = session.createQuery(hql);
Iterator<Entry<String, Object>> it = args.entrySet().iterator();
while (it.hasNext()) {
Entry<String, Object> entry = it.next();
query.setParameter(entry.getKey(), entry.getValue());
}
@SuppressWarnings("unchecked")
List<Object> list = query.list();
this.closeHibernateSession(sessionFactory); // I don't even know if I should need this!
if (list!=null && list.size() > 0) {
return list.get(0);
} else {
log4j.warn("readObject: List is NULL.");
return null;
}
}
protected Session openHibernateSession(SessionFactory sessionFactory) {
Session session = null;
try {
session = sessionFactory.getCurrentSession();
} catch (HibernateException ex) {
session = sessionFactory.openSession();
}
return session;
}
protected void closeHibernateSession(SessionFactory sessionFactory){
Session session;
try {
if (sessionFactory.getCurrentSession()!=null) {
session = sessionFactory.getCurrentSession();
session.close();
}
} catch (HibernateException ex) {
log4j.warn("Failed to close current session, set session to null.", ex);
session = null;
}
}
提前干杯。
是的,它几乎是一团糟,所以我把它剥了下来,发现了几个例子并重新开始。
@Transactional
public class UserDaoImpl UserDao {
@Autowired
private SessionFactory sessionFactory;
private Session session;
private Query query;
@Override
public UserDetails getUserDetails(Integer id) {
session = sessionFactory.getCurrentSession();
Query query = session.createQuery("FROM UserDetails WHERE id = "+id);
UserDetails userDetails = (UserDetails) query.list().get(0);
return userDetails;
}
}
并对我的application-context.xml进行了一些更改
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<tx:annotation-driven/>
现在似乎工作正常,因为在10次连接后我没有挂起。
只是想知道我是否需要打扰session.close();或者现在应该处理这个?
干杯。
答案 0 :(得分:2)
您可能没有关闭Connections,将它们返回池中。
maxPoolSize
是一个限制因素;如果你的代码占用了Connections&amp;没有close()
他们,C3PO不知道他们可以进行第11次搜索。
空闲时间与它无关。 C3PO无法很好地关闭/回收连接,而您似乎还在使用它,是吗?空闲时间的目的是消除长时间空闲的连接,数据库可能已经关闭了它们。
阻止您的代码关闭会话的具体问题是对sessionFactory.getCurrentSession()
的依赖。您尚未在那里注册当前会话,因此无效。
最好直接关闭会话。
在webapps中,我使用Spring OpenSessionInView模式&amp;一些变种(长会话)。
我建议使用/制作一些定义良好的基础设施来获取SessionFactory,获取Sessions(可能绑定到当前线程),并从当前线程绑定/取消绑定Sessions。
随着您的应用变得越来越大,将所有这些内容放在明确定义的位置会有所帮助。
答案 1 :(得分:1)
我不知道你从哪里得到这个代码,但这是错的。我的猜测是openHibernateSession()
总是进入catch块,因此打开一个会话,因为没有当前的会话。
然后closeHibernateSession()
,甚至没有在finally块中调用,尝试再次获取当前会话,仍然找不到任何内容,因此不执行任何操作。特别是,它不会关闭openHibernateSession()
打开的会话。
因此,只要执行此代码10次,您仍然会打开10个会话,因此有10个连接尚未关闭并返回到连接池。
重新阅读有关Spring和Hibernate集成的文档。你不应该自己打开会话。只使用getCurrentSession()
,让Spring处理它们。