【问题标题】:Hibernate/mysql connection poolingHibernate/mysql 连接池
【发布时间】:2009-04-11 15:09:25
【问题描述】:

我们托管一个服务(在 jboss 上运行的 servlet),它每秒接收大约 5-6 个请求。每个请求都需要通过hibernate连接到mysql。我们的大多数请求都进行选择,每 5/6 个请求插入/更新一次。休眠 mysql 连接在 mysql 连接超时期限(8 小时)后超时。即使在请求 ping 我们的服务之后,每隔一小时,mysql 连接有时也会在一天左右后随机断开。我们希望 hibernate 在连接因任何原因断开连接的情况下重新连接,并保持我们希望的连接数。

我们尝试了 C3P0,配置如下:

<property name=c3p0.acquire_increment>1</property>
<property name=c3p0.idle_test_period>3600</property> 
<property name=c3p0.max_statements>0</property> 
<property name=c3p0.min_size>1</property> 
<property name=c3p0.timeout>3605</property> 
<property name=hibernate.c3p0.preferredTestQuery>select 1;</property>

休眠连接池大小设置为 1。

这使超时/断开连接问题消失了。但我们开始面临另一个问题。漫长的等待。通常我们的请求服务时间是 2-3ms 的选择和 40-50ms 的插入/更新。但是,在使用上述 C3P0 配置后,我们看到更新后完成的每个请求都需要一分钟以上,有时甚至需要 4-5 分钟!从我们的日志来看,似乎随机选择请求会卡住,并且只有在收到并提供更新请求后才能完成。

如果我们删除 C3P0 配置,上述问题就会消失。有人可以建议我们可能做错了什么吗?

这是完整的休眠配置供参考:

<?xml version="1.0" encoding="utf-8" ?>

<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>

        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://xxx.xxx.xxx</property>
        <property name="connection.username">xxx</property>
        <property name="connection.password">xxx</property>
        <property name="connection.pool_size">1</property> 
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="current_session_context_class">thread</property>
        <property name="hibernate.cache.use_query_cache">false</property>
        <property name="hibernate.cache.use_second_level_cache">false</property>
        <property name="show_sql">true</property>

        <!-- Transaction isolation 2 = READ_COMMITTED -->
        <property name="connection.isolation">2</property>
        <property name="connection.autocommit">true</property>

        <!-- configuration pool via c3p0-->
        <property name="c3p0.acquire_increment">1</property>
        <property name="c3p0.idle_test_period">3600</property> <!-- seconds -->
        <property name="c3p0.max_size">1</property>
        <property name="c3p0.max_statements">0</property>
        <property name="c3p0.min_size">1</property>
        <property name="c3p0.timeout">3605</property> <!-- seconds -->
        <property name="hibernate.c3p0.preferredTestQuery">select 1;</property>

    </session-factory>
</hibernate-configuration>

【问题讨论】:

    标签: java mysql hibernate


    【解决方案1】:

    我建议放弃 C3P0 并使用 JBOSS 提供的 JNDI 命名服务和连接池。

    确保您正确关闭连接并将它们返回到池中。连接、查询、关闭,所有这些都在尽可能小的范围内。八小时内不应有任何连接。

    更多链接可能是相关的:http://www.hibernate.org/117.htmlhttp://www.informit.com/articles/article.aspx?p=353736&seqNum=4 关于 Hibernate 和关闭连接,以及这个 MySQL 错误引用了 MySQL、Hibernate 和连接问题:http://bugs.mysql.com/bug.php?id=10917

    【讨论】:

    • hmmm,目前我们将连接管理完全留在休眠状态,即我们只向休眠状态询问当前连接(getCurrentConnection()),然后对其执行查询。我们从不在代码中显式打开或关闭连接。或许,我们需要重新审视该策略。
    • 但是我们也有高性能要求(
    • @ashweta:你需要阅读这个 - hibernate.org/117.html。搜索“Hibernate 正在泄漏 JDBC 连接!”必须关闭会话。就性能而言,这就是您拥有池的原因。在这种情况下,“关闭”实际上意味着“返回池”。
    • 我认为你说的是​​对的。查询后我们没有关闭连接。因此,我们的连接仅在提交时才关闭。我们尝试将 session.close() 放在执行查询的函数中,从我们的测试到现在,它似乎解决了问题!
    【解决方案2】:

    您的配置似乎有问题。所有配置参数都应该在 hibernate.c3p0 命名空间中,而不是 c3p0.*。

    但这可能不是问题所在。我认为您的池很可能只有一个连接大,并且您在某处遇到资源争用问题。很可能没有在你应该释放的地方释放连接,或者某些数据出现死锁。尝试将 maxPoolsize 设置为更高的值,例如 2,看看问题是否得到缓解。这可能意味着您没有正确返回连接。

    【讨论】:

      【解决方案3】:

      JBoss Hibernate 文档特别声明不要将 Hibernate 连接池管理器用于非生产系统(就像 Hypersonic - 我真的不知道他们为什么要费心发布已知的有缺陷的组件) .如前所述,使用标准的 JBoss &lt;datasource&gt; 设置和关联的池管理器(并根据需要进行配置)。

      有一些误解是open()close() 方法被连接管理器覆盖。甚至 Connection 对象也不是直接连接到数据库,而是池管理器的句柄。

      获得新连接(也称为打开)时的实现是从池中请求一个连接(为了提高效率,该连接已经打开,如果使用datasource 定义中的&lt;prepared-statement-cache-size&gt; 属性进行配置,则还具有先前的@ 987654327@s 仍然绑定到 Connection)。这个调用非常高效。

      当在连接上调用close() 时(同样,由池管理器实现),连接引用状态简单地更改为“可用”,而不是关闭实际的数据库连接。这也是超级高效的。因此,建议将 open/exec/close 调用的范围尽可能小,以最大限度地利用池中的可用连接进行多线程使用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-25
        • 2013-08-20
        • 1970-01-01
        • 2022-08-09
        • 2015-08-19
        • 2015-04-14
        • 1970-01-01
        • 2017-12-01
        相关资源
        最近更新 更多