如何在Hibernate中禁用连接池。

5
我有一个网络应用程序,目前使用c3p0和Hibernate连接到Firebird 1.5数据库。但是,我经常会遇到数据库突然停止响应的问题,即使手动重启服务也没有任何效果,也不会生成任何日志。因此,我必须手动重新启动计算机才能使其正常工作。我认为可能是当池尝试获取特定数量的连接时,Firebird挂起了,所以我需要测试我的应用程序而不使用连接池,以检查这是否是问题。
我不能简单地从持久性中删除c3p0配置,因为这样Hibernate将使用自己集成的连接池。那么,如何实现呢?

1
我知道这不是一个立即的解决方案,但你真的应该考虑升级你的Firebird安装。最后一个Firebird 1.5发布已经6年了;从那时起修复了各种各样的错误(如果你还没有升级到1.5.6,至少要升级到那个版本)。 - Mark Rotteveel
很遗憾,这是不可能的,因为一些 Delphi 应用程序使用的组件仅与 Firebird 1.5 绑定。 - Mateus Viccari
3个回答

3
最灵活的解决方案是使用显式的数据源,而不是通过Hibernate配置连接池。配置非池化DataSource的一种选项是使用DriverManagerDataSource
@Override
protected Properties getProperties() {
    Properties properties = new Properties();
    properties.put("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
    //log settings
    properties.put("hibernate.hbm2ddl.auto", "update");
    //data source settings
    properties.put("hibernate.connection.datasource", newDataSource());
    return properties;
}

protected ProxyDataSource newDataSource() {
    DriverManagerDataSource actualDataSource = new DriverManagerDataSource();
    actualDataSource.setUrl("jdbc:hsqldb:mem:test");
    actualDataSource.setUsername("sa");
    actualDataSource.setPassword("");
    ProxyDataSource proxyDataSource = new ProxyDataSource();
    proxyDataSource.setDataSource(actualDataSource);
    proxyDataSource.setListener(new SLF4JQueryLoggingListener());
    return proxyDataSource;
}

这样,您可以选择使用池化或非池化的DataSource
为了更好地了解您的连接池资源使用情况,您可以配置FlexyPool来收集以下指标:
  • 并发连接数
  • 并发连接请求
  • 数据源连接获取时间
  • 连接租约时间
  • 最大池大小
  • 总连接获取时间
  • 溢出池大小
  • 重试次数

2
但这也会利用连接池...这就是问题(我认为),我需要一些东西,使每个session的open()和close()调用实际上创建一个连接并关闭它,而不会在池中闲置打开的连接。 - Mateus Viccari
然后,只需提供不带池化的JDBC驱动程序数据源或Spring的DriverManagerDataSource。这将不会有任何池化。 - Vlad Mihalcea
很遗憾我没有时间测试,但我一定会尽快测试并在这里回复! - Mateus Viccari

1

我发现了关于hibernate 3.34.3 的文档,其中说:

只需使用连接池特定的设置替换 hibernate.connection.pool_size 属性,就可以关闭 Hibernate 的内部连接池。

如果您设置了 hibernate.c3p0.* 属性,则 Hibernate 将使用其 org.hibernate.connection.C3P0ConnectionProvider 用于连接池。

因此,从配置中删除 hibernate.connection.pool_size 和任何 hibernate.c3p0... 属性,即可禁用连接池。


1
Hibernate 5.6在没有这些属性时使用内置连接池:HHH10001002: 使用Hibernate内置连接池(不适用于生产环境!) - Wortig

1

补充Vlad的回答:

如果有人仍然遇到这个问题:

  • 请务必从类路径中删除"hibernate-c3p0",如果存在的话,因为这会自动启用MChange c3p0连接池。

  • 另一个选项是,在关闭实体管理器时手动关闭连接:

              ....
              SessionImpl ses = (SessionImpl) session;
              close(ses.connection());
              try {
                  session.close();
              } catch (Exception e) {
                  logger.error(e);
              }
              ........
    

祝你好运


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接