为了避免死锁,什么是休眠所需的C3P0设置 [英] What are the required C3P0 settings for hibernate in order to avoid Deadlocks

查看:117
本文介绍了为了避免死锁,什么是休眠所需的C3P0设置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用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>
<! - 数据库连接设置 - >
< 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>

<! - 使用C3P0连接池提供者 - >
< 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方言 - >
< property name =dialect> org.hibernate.dialect.MySQLDialect< / property>

<! - 启用Hibernate的自动会话上下文管理 - >
< property name =current_session_context_class>线程< / property>

<! - 禁用二级缓存 - >
< property name =cache.provider_class> org.hibernate.cache.NoCacheProvider< / property>

<! - 将所有执行的SQL回复到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中。他们每个人都使用休眠配置文件几乎相当于上面所示(只有用户名,数据库名,密码和映射resoruces更改)。



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

  2009年1月22日下午3点29分07秒com.mchange.v2.async.ThreadPoolAsynchronousRunner $ DeadlockDetector运行
警告:com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@2437d - APPARENT DEADLOCK !!!为未分配的待处理任务创建紧急线程!
Jan 22,2009 3:29:07 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner $ DeadlockDetector运行
警告:com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@1dc5cb7 - APPARENT DEADLOCK! !为未分配的待处理任务创建紧急线程!
Jan 22,2009 3:29:07 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner $ DeadlockDetector运行
警告:com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@9cd2ef - APPARENT DEADLOCK! !为未分配的待处理任务创建紧急线程!
Jan 22,2009 3:29:07 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner $ DeadlockDetector运行
警告:com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@4af355 - APPARENT DEADLOCK! !为未分配的待处理任务创建紧急线程!
Jan 22,2009 3:29:07 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner $ DeadlockDetector运行
警告:com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@1275fcb - APPARENT DEADLOCK! !为未分配的待处理任务创建紧急线程!
Jan 22,2009 3:29:35 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner $ DeadlockDetector run

这似乎是几个人已经得到的错误。我更改了我的设置,试图按照此处所述的解决方法 http://forum.hibernate.org/ viewtopic.php?p = 2386237 到:

 <属性名称=hibernate.c3p0.acquire_increment> 1 LT; /性> 
< 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>

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

 警告:SQL错误:0,SQLState:08S01 
Jan 24,2009 5:53:37 AM org.hibernate.util.JDBCExceptionReporter logExceptions
SEVERE:由于潜在异常导致的通信链接失败:

** BEGIN NESTED EXCEPTION **

java.io.EOFException

STACKTRACE:

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

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

解决方案实际上这可能太晚了,但问题很简单:
hibernate.c3p0.idle_test_periods 不能高于 hibernate.c3p0.timeout 或由数据库关闭的连接将不会被正确检测到。



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

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



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


I use Hibernate together with MySQL 5.1.30.

I have the next libraries:

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

I use a hibernate.cfg.xml for configuration:

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

In the JAVA persistance with hibernate book, c3p0 configuration options are explained:

  • hibernate.c3p0.min_size This is the minimum number of JDBC connections that C3P0 keeps ready at all times
  • hibernate.c3p0.max_size This is the maximum number of connections in the pool. An exception is thrown at runtime if this number is exhausted.
  • hibernate.c3p0.timeout You specify the timeout period (in this case, 300 seconds) after which an idle connection is removed from the pool).
  • hibernate.c3p0.max_statements Maximum Number of statements that will be cached. Caching of prepared statements is essential for best performance with Hibernate.
  • hibernate.c3p0.idle_test_periods This is the iddle time in seconds before a connection is automatically validated.

I use Java 1.5.0_09 and tomcat 6.0. I have three applications deployed in tomcat. Each of them uses hibernate with a configuration file almost equivalent the shown above (only username, databasename, password and the mapping resoruces change).

Unfortunately with the above settings, after some hours running i get some nasty Deadlock errors which end killing 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

This seems to be an error several people already got. I changed my settings trying to follow the workaround described herehttp://forum.hibernate.org/viewtopic.php?p=2386237 to:

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

With the new settings, I do not get Deadlocks, but I get:

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)

Does anyone knows what I am doing wrong, and how I can setup c3p0 correctly?

解决方案

Actually this is probably too late, but the problem is quite simple: hibernate.c3p0.idle_test_periods must not be higher than hibernate.c3p0.timeout or connections closed by the database will not be properly detected.

Moreover, the deadlock detection warnings look like some part of your code is not properly returning the connections to the pool (i.e. session.close())

The MysqlIO exceptions occur when your application idles and MySQL closes the connection on the server. Now if C3P0 does not properly check whether a connection is still actually connected you get the EOFExceptions.

I hope this might be helpful.

这篇关于为了避免死锁,什么是休眠所需的C3P0设置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆