Home Articles

Hibernate / mysql连接池

Asked
Viewed 453 times
1

我们托管一个服务(在jboss上运行的servlet),每秒接收5-6个请求 . 每个请求都需要通过hibernate连接到mysql . 我们的大多数请求都会选择,每隔5/6请求插入/更新一次 . 在mysql连接超时(8小时)之后,hibernate mysql连接会超时 . 即使在请求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>

Hibernate connection_pool大小设置为1 .

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

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

这是完整的hibernate配置供参考:

<?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>

3 Answers

  • 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

  • 1

    JBoss Hibernate文档特别声明 not 使用Hibernate连接池管理器用于非 生产环境 系统(就像Hypersonic一样 - 我真的不知道为什么他们懒得运送已知的bug组件) . 如前所述,使用标准JBoss <datasource> 设置和关联的池管理器(并根据需要进行配置) .

    存在一些误解的地方是 open()close() 方法被连接管理器覆盖 . 即使 Connection 对象也不是与数据库的直接连接,而是池管理器的句柄 .

    获得新连接(也称为打开)时的实现是从池请求连接(为了提高效率,如果使用 datasource 定义中的 <prepared-statement-cache-size> 属性进行配置,之前 PreparedStatement 仍然绑定到 Connection ) . 这个电话非常有效率 .

    当在Connection上调用 close() 时(同样,由池管理器实现),连接引用状态只是更改为'available'而不是关闭实际的数据库连接 . 这也是非常有效的 . 因此,建议尽可能小的open / exec / close调用范围,以最大化池中可用连接的多线程使用 .

  • 0

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

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

Related