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

发布于 2024-07-12 02:45:24 字数 5748 浏览 8 评论 0原文

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

帅的被狗咬 2024-07-19 02:45:24

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

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

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

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

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.

梨涡少年 2024-07-19 02:45:24

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

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

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

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

近似值

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

maxStatements 和 maxStatementsPerConnection 应该测试几个月,因为很少有发布会因为这些参数而导致死锁。

参考这些链接也会很有用;

There is no definitive answer to this question, as it changes from application to application depending on the usage & load pattern.

First point is refer the link https://www.hibernate.org/214.html, since it seems you've done that and gone ahead. here are a few tips;

  • numHelperThreads : Helper threads that don't hold contended locks. Spreading these operations over multiple threads
  • maxStatements : The size of c3p0's global PreparedStatement cache.
  • maxStatementsPerConnection : The number of PreparedStatements c3p0 will cache for a single pooled Connection.
  • maxAdministrativeTaskTime : Parameter that force a call to the task thread's interrupt() method if a task exceeds a set time limit

First three parameter can improve or reduce the performance based on the value set where as forth parameter can interrupt the thread after set limit and give a change to run to other thread.

Approximate values

  • numHelperThreads = 6
  • maxStatements =100
  • maxStatementsPerConnection = 12
  • maxAdministrativeTaskTime = need to sufficient time so that heavy query can run on production

maxStatements and maxStatementsPerConnection should be tested for few months as few posting point to dead lock because of these parameter.

Also referring to these links will be useful;

夜访吸血鬼 2024-07-19 02:45:24

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

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

如果idle_test_periods大于超时参数,则休眠会查找系统中任何为空或不存在的内容。 至少我是这样理解的。

The hibernate.c3p0.idle_test_periods have to be less than h*ibernate.c3p0.timeout* because the first is just only a time value where hibernate check for idle connections and try to close it.

Meanwhile the second is just how much time a connection need to be ejected.

If the idle_test_periods is bigger than timeout parameter than hibernate look for anything that is null or not exist in the system. At least I understood in this way.

月亮邮递员 2024-07-19 02:45:24
    <property name="hibernate.c3p0.timeout">300</property>     
    <property name="hibernate.c3p0.idle_test_periods">3000</property>       

idle_test_period 值应小于超时值。

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

idle_test_period value should be less than equal of time out value.

小傻瓜 2024-07-19 02:45:24

这是 Connector/J 的一个相当旧的版本。 为了确保您没有遇到已知且已修复的错误,我首先获取最新的错误(5.0.8):

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

来自MysqlIOEOFException code> 有点可疑。 在正常/无错误的使用情况下,您不应该从该层收到错误。

That's a pretty old version of Connector/J. To make sure you're not battling a known and fixed bug, I'd start by getting the newest one (5.0.8):

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

That EOFException from MysqlIO is a bit suspicious. Under normal/non-buggy usage, you shouldn't ever get errors from that layer.

小嗷兮 2024-07-19 02:45:24

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

Do the three applications share the same connection pool, or does each one get its own? I'd recommend the latter.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文