49

我将 Hibernate 与 MySQL 5.1.30 一起使用。

我有下一个库:

  • c3p0-0.0.1.2.jar
  • mysql-connector-java-5.0.3-bin.jar
  • hibernate3.jar

我使用 hibernate.cfg.xml 进行配置:

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

<hibernate-configuration>
    <session-factory>
        <!-- Database connection settings -->
        <property name="connection.driver_class">org.gjt.mm.mysql.Driver</property> 

        <property name="connection.url">jdbc:mysql://localhost/fooDatatbase</property>
    <property name="connection.username">foo</property>
    <property name="connection.password">foo123</property>

        <!-- Use the C3P0 connection pool provider -->
    <property name="hibernate.c3p0.min_size">5</property>
    <property name="hibernate.c3p0.max_size">20</property>
    <property name="hibernate.c3p0.timeout">300</property>
    <property name="hibernate.c3p0.max_statements">50</property>
    <property name="hibernate.c3p0.idle_test_periods">3000</property>       

        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>

        <!-- Disable the second-level cache  -->
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>

        <mapping resource="databaselayer/mail/Mail.hbm.xml"/>
        <mapping resource="databaselayer/courses/Course.hbm.xml"/>
        <mapping resource="databaselayer/price/Price.hbm.xml"/>        
        <mapping resource="databaselayer/contact/Contact.hbm.xml"/>
        <mapping resource="databaselayer/artists/Musician.hbm.xml"/>
        <mapping resource="databaselayer/concerts/Concert.hbm.xml"/>     
        <mapping resource="databaselayer/welcome/Welcome.hbm.xml"/>
        <mapping resource="databaselayer/information/Information.hbm.xml"/>                             
    </session-factory>
</hibernate-configuration>

JAVA persistence with hibernate一书中,对 c3p0 配置选项进行了解释:

  • hibernate.c3p0.min_size这是 C3P0 始终保持就绪的最小 JDBC 连接数
  • hibernate.c3p0.max_size这是池中的最大连接数。如果此数字用尽,则在运行时引发异常。
  • hibernate.c3p0.timeout您指定从池中删除空闲连接的超时时间(在本例中为 300 秒)。
  • hibernate.c3p0.max_statements将被缓存的最大语句数。缓存准备好的语句对于 Hibernate 的最佳性能至关重要。
  • hibernate.c3p0.idle_test_periods这是自动验证连接之前的中间时间(以秒为单位)。

我使用 Java 1.5.0_09 和tomcat 6.0。我在 tomcat 中部署了三个应用程序。他们每个人都使用 hibernate 和一个几乎等同于上面显示的配置文件(只有用户名、数据库名、密码和映射资源发生变化)。

不幸的是,使用上述设置,运行几个小时后,我得到了一些令人讨厌的死锁错误,最终杀死了 tomcat。

Jan 22, 2009 3:29:07 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run
WARNING: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@2437d -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
Jan 22, 2009 3:29:07 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run
WARNING: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@1dc5cb7 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
Jan 22, 2009 3:29:07 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run
WARNING: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@9cd2ef -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
Jan 22, 2009 3:29:07 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run
WARNING: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@4af355 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
Jan 22, 2009 3:29:07 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run
WARNING: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@1275fcb -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
Jan 22, 2009 3:29:35 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run

这似乎是几个人已经遇到的错误。我将设置更改为尝试遵循此处描述的解决方法http://forum.hibernate.org/viewtopic.php?p=2386237为:

<property name="hibernate.c3p0.acquire_increment">1</property>
<property name="hibernate.c3p0.min_size">0</property>
<property name="hibernate.c3p0.max_size">48</property>
<property name="hibernate.c3p0.timeout">0</property>
<property name="hibernate.c3p0.max_statements">0</property>

使用新设置,我不会遇到死锁,但我会:

WARNING: SQL Error: 0, SQLState: 08S01
Jan 24, 2009 5:53:37 AM org.hibernate.util.JDBCExceptionReporter logExceptions
SEVERE: Communications link failure due to underlying exception: 

** BEGIN NESTED EXCEPTION ** 

java.io.EOFException

STACKTRACE:

java.io.EOFException
    at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1913)

有谁知道我做错了什么,以及如何正确设置 c3p0?

4

6 回答 6

54

实际上这可能为时已晚,但问题很简单: hibernate.c3p0.idle_test_periods不能高于hibernate.c3p0.timeout或无法正确检测到数据库关闭的连接。

此外,死锁检测警告看起来像您的代码的某些部分没有正确地将连接返回到池(即 session.close())

当您的应用程序空闲并且 MySQL 关闭服务器上的连接时,会发生 MysqlIO 异常。现在,如果 C3P0 没有正确检查连接是否仍然实际连接,您将获得 EOFExceptions。

我希望这可能会有所帮助。

于 2010-09-17T00:52:26.110 回答
10

这个问题没有明确的答案,因为它会根据使用情况和负载模式在应用程序之间发生变化。

第一点是参考链接https://www.hibernate.org/214.html,因为您似乎已经这样做了并且继续前进。这里有一些提示;

  • numHelperThreads :不持有竞争锁的辅助线程。将这些操作分布在多个线程上
  • maxStatements :c3p0 的全局 PreparedStatement 缓存的大小。
  • maxStatementsPerConnection :PreparedStatements c3p0 将为单个池连接缓存的数量。
  • maxAdministrativeTaskTime :如果任务超过设定的时间限制,则强制调用任务线程的中断()方法的参数

前三个参数可以根据设置的值提高或降低性能,其中第四个参数可以在设置限制后中断线程并改变运行到其他线程。

近似值

  • numHelperThreads = 6
  • 最大语句数 =100
  • maxStatementsPerConnection = 12
  • maxAdministrativeTaskTime = 需要足够的时间才能在生产环境中运行繁重的查询

maxStatements 和 maxStatementsPerConnection 应该测试几个月,因为由于这些参数,很少有帖子指向死锁。

也参考这些链接将是有用的;

于 2009-08-13T15:14:29.563 回答
3

hibernate.c3p0.idle_test_periods必须小于 h* ibernate.c3p0.timeout * 因为第一个只是休眠检查空闲连接并尝试关闭它的时间值。

同时,第二个是需要弹出连接的时间。

如果 idle_test_periods 大于 timeout 参数而不是 hibernate 则查找系统中为 null 或不存在的任何内容。至少我是这样理解的。

于 2014-01-10T10:29:05.747 回答
2
    <property name="hibernate.c3p0.timeout">300</property>     
    <property name="hibernate.c3p0.idle_test_periods">3000</property>       

idle_test_period 值应小于等于超时值。

于 2017-08-29T21:02:25.337 回答
1

那是Connector/J 的一个相当老的版本。为了确保您没有与已知且已修复的错误作斗争,我将从获取最新的错误(5.0.8)开始:

http://dev.mysql.com/downloads/connector/j/5.0.html

这有点可疑EOFExceptionMysqlIO在正常/非错误使用情况下,您不应该从该层得到错误。

于 2009-08-18T00:03:41.793 回答
0

三个应用程序共享同一个连接池,还是每个应用程序都有自己的连接池?我推荐后者。

于 2009-01-24T13:33:07.073 回答