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 错误吗?

4

3 回答 3

14

这会立即发生,还是在一段时间后发生?也就是说,结帐最初是否成功,但随后就这样挂起?如果是这样,它看起来像一个连接泄漏。请尝试设置 c3p0 参数 unreturnedConnectionTimeout 和 debugUnreturnedConnectionStackTraces 以查看是否存在泄漏。见 http://www.mchange.com/projects/c3p0/#configuring_to_debug_and_workaround_broken_clients , http://www.mchange.com/projects/c3p0/#unreturnedConnectionTimeout , http://www.mchange.com/projects/c3p0/# debugUnreturnedConnectionStackTraces

如果这种情况立即发生,如果没有成功签出连接,问题是池是否成功获取连接。默认情况下,如果它从未成功,大约 30 秒后,您的线程应该会因失败而中断。(看起来您并没有这样做,但如果您将 acquireRetryAttempts 设置为零,c3p0 可能会无限期地挂起等待连接。)

要调试 c3p0 问题,捕获 c3p0 在池初始化时以 INFO 级别转储到日志的版本和配置信息会很有帮助。

祝你好运!

于 2013-01-01T07:30:33.160 回答
3

此外,您似乎还没有初始化 c3p0 的 checkoutTime 参数,该参数指定客户端应等待从连接池获取连接的时间量。

http://www.mchange.com/projects/c3p0/#checkoutTimeout

于 2013-08-26T05:57:12.623 回答
0

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

于 2021-01-28T16:11:04.217 回答