休眠所需的C3P0设置是什么,以避免死锁

时间:2009-01-24 11:31:09

标签: hibernate c3p0

我将Hibernate与MySQL 5.1.30一起使用。

我有下一个库:

  • c3p0-0.0.1.2.jar
  • MySQL的连接器的Java-5.0.3-bin.jar
  • hibernate.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 persistance 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,配置文件几乎等同于上面显示的(只有用户名,数据库名,密码和映射resoruces更改)。

不幸的是,通过以上设置,经过几个小时的运行后,我得到了一些令人讨厌的死锁错误,最终杀死了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?

6 个答案:

答案 0 :(得分:48)

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

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

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

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

答案 1 :(得分:8)

这个问题没有明确的答案,因为它会根据使用情况而从应用程序变为应用程序。负载模式。

第一点是参考链接https://www.hibernate.org/214.html,因为看起来你已经完成了这项工作并继续进行。这里有一些提示;

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

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

近似值

  • numHelperThreads = 6
  • maxStatements = 100
  • maxStatementsPerConnection = 12
  • maxAdministrativeTaskTime =需要足够的时间,以便可以在生产上运行繁重的查询
由于这些参数,

maxStatements和maxStatementsPerConnection应该测试几个月,因为很少发布指向死锁。

同时参考这些链接也很有用;

答案 2 :(得分:3)

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

与此同时,第二个问题是连接需要多长时间才能弹出。

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

答案 3 :(得分:1)

这是一个非常古老的Connector / J版本。为了确保你没有与一个已知和修复过的bug作斗争,我首先要获得最新的bug(5.0.8):

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

来自EOFException的{​​{1}}有点可疑。在正常/非错误使用情况下,您不应该从该层获得错误。

答案 4 :(得分:1)

    <property name="hibernate.c3p0.timeout">300</property>     
    <property name="hibernate.c3p0.idle_test_periods">3000</property>       

idle_test_period值应小于等于超时值。

答案 5 :(得分:0)

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