为了避免死锁,什么是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进行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>
在使用hibernate的JAVA持久性书中,解释了c3p0configuration选项:
- hibernate.c3p0.min_size这是C3P0始终准备好的JDBC连接的最小数量
- hibernate.c3p0.max_size这是池中的最大连接数。 如果这个数字用完了,运行时会抛出一个exception。
- hibernate.c3p0.timeout指定从池中删除空闲连接的超时时间(在本例中为300秒)。
- hibernate.c3p0.max_statements最大数量的将被caching的语句。 准备好的语句的caching对于Hibernate的最佳性能至关重要。
- hibernate.c3p0.idle_test_periods这是连接自动validation之前的空闲时间(以秒为单位)。
我使用Java 1.5.0_09和tomcat 6.0 。 我有三个应用程序部署在tomcat。 他们每个人都使用hibernateconfiguration文件几乎相当于上面所示(只有用户名,数据库名,密码和映射resoruces更改)。
不幸的是,有了上述设置,经过几个小时的运行,
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?
其实这可能太晚了,但问题很简单: hibernate.c3p0.idle_test_periods
一定不能高于hibernate.c3p0.timeout
否则数据库closures的连接将无法正常检测。
此外,死锁检测警告看起来像你的代码的一部分是不正确地返回连接池(即session.close())
当您的应用程序空闲并且MySQLclosures服务器上的连接时,将发生MysqlIOexception。 现在,如果C3P0没有正确地检查一个连接是否实际连接,你会得到EOFExceptions。
我希望这可能会有所帮助。
这个问题没有明确的答案,因为它根据使用和加载模式从应用程序改变到应用程序。
第一点是参考链接https://www.hibernate.org/214.html ,因为看起来你已经做到了,走在前面。 这里有一些提示;
- numHelperThreads:不包含竞争锁的助手线程。 将这些操作分散在多个线程上
- maxStatements:c3p0全局PreparedStatementcaching的大小。
- maxStatementsPerConnection:PreparedStatements c3p0的数目将caching一个池连接。
- maxAdministrativeTaskTime:如果任务超过设定的时间限制,则强制调用任务线程的interrupt()方法的参数
前三个参数可以根据第四个参数设置的限制后可以中断线程的数值来改善或者降低性能,并且改变运行到其他线程。
近似值
- numHelperThreads = 6
- maxStatements = 100
- maxStatementsPerConnection = 12
- maxAdministrativeTaskTime =需要足够的时间,以便大量查询可以在生产中运行
因为这些参数,maxStatements和maxStatementsPerConnection应该testing几个月,因为发布点死锁。
也指这些链接将是有用的;
hibernate.c3p0.idle_test_periods必须小于h * ibernate.c3p0.timeout *,因为第一个只是一个时间值,hibernate会检查空闲连接并尝试closures它。
与此同时,第二个是连接需要popup多less时间。
如果idle_test_periods比timeout参数大,则hibernate会查找系统中存在或不存在的任何内容。 至less我是这样理解的。
这是一个相当旧的Connector / J版本。 为了确保你没有和一个已知的固定错误作斗争,我会从最新的(5.0.8)开始:
http://dev.mysql.com/downloads/connector/j/5.0.html
来自MysqlIO
EOFException
有点可疑。 在正常/没有错误的使用情况下,您不应该从该层获取错误。
这三个应用程序共享相同的连接池,还是每个都有自己的连接池? 我会推荐后者。
<property name="hibernate.c3p0.timeout">300</property> <property name="hibernate.c3p0.idle_test_periods">3000</property>
idle_test_period值应该小于等于超时值。