c3p0和hibernate一起使用时处于awaitAvailable状态

6

我有一个控制台应用程序,在执行过程中出现了卡顿。以下是我的配置:

    cfg.setProperty("hibernate.connection.driver_class", "com.mysql.jdbc.Driver");
    cfg.setProperty("hibernate.connection.url", "jdbc:mysql://localhost:3306/db?user=db&password=db");
    cfg.setProperty("hibernate.connection.username", "db");
    cfg.setProperty("hibernate.connection.password", "db");
    cfg.setProperty("hibernate.connection.pool_size", "5");
    cfg.setProperty("hibernate.connection.autocommit", "false");
    cfg.setProperty("hibernate.c3p0.min_size", "5");
    cfg.setProperty("hibernate.c3p0.max_size", "20");
    cfg.setProperty("hibernate.c3p0.timeout", "300");
    cfg.setProperty("hibernate.c3p0.max_statements", "50");
    cfg.setProperty("hibernate.c3p0.idle_test_period", "3000");

这是我的堆栈跟踪:

"main" prio=10 tid=0x000000000168f800 nid=0x1c37 in Object.wait() [0x00007fa60d0ad000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000007400f4c68> (a com.mchange.v2.resourcepool.BasicResourcePool)
        at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1315)
        at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:557)
        - locked <0x00000007400f4c68> (a com.mchange.v2.resourcepool.BasicResourcePool)
        at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:477)
        at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:525)
        at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:128)
        at org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider.getConnection(C3P0ConnectionProvider.java:84)
        at org.hibernate.internal.AbstractSessionImpl$NonContextualJdbcConnectionAccess.obtainConnection(AbstractSessionImpl.java:281)
        at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:297)
        at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.getConnection(LogicalConnectionImpl.java:169)
        at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:67)
        at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:160)
        at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1392)
        at org.kriyak.parser.IndexArchiveRapid.indexFile(IndexArchiveRapid.java:70)
        at org.kriyak.parser.IndexArchiveRapid.main(IndexArchiveRapid.java:53)

我只打开了一个连接,似乎没有泄漏。而且我只使用了一个线程。除了内存使用之外,我没有调整过任何mysql设置。从控制台上看,mysql正常运行。为什么会出现这种情况?是c3p0错误吗?


你的应用程序中只有这一个线程吗? - parsifal
是的,它是唯一的线程。 - Stepan Yakovenko
3个回答

14

这个问题是立即发生还是一段时间后发生的?也就是说,初始时结帐成功,但之后卡住了吗?如果是这样,看起来像是连接泄漏。请尝试设置c3p0参数unreturnedConnectionTimeout和debugUnreturnedConnectionStackTraces以查看是否存在泄漏。参见http://www.mchange.com/projects/c3p0/#configuring_to_debug_and_workaround_broken_clientshttp://www.mchange.com/projects/c3p0/#unreturnedConnectionTimeouthttp://www.mchange.com/projects/c3p0/#debugUnreturnedConnectionStackTraces

如果问题是立即发生的,也就是没有成功获取任何连接,那么问题在于池是否曾经成功地获取过连接。默认情况下,如果它永远不成功,在大约30秒后,您的线程应该会因为失败而中断。(看起来您没有这样做,但例如,如果您将acquireRetryAttempts设置为零,c3p0可能会无限期地等待连接。)

为了调试c3p0问题,有助于捕获c3p0在INFO级别的池初始化时转储到日志中的版本和配置信息。

祝您好运!


我没有关闭底层连接,而这在我的情况下是明确要求的。 - Niranjan

3

0
您可能需要增加c3p0.numHelperThreads。助手线程负责创建新的数据库连接并将其添加到池中。如果没有足够的线程来满足需求,那么应用程序线程将被卡在awaitAvailable()中等待。要确认这种情况,请查看所有HelperThreads,并查看它们是否都在使用中并正在连接到数据库。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接