3

我的应用程序在使用 Hibernate 与 MySQL 数据库通信时偶尔会看到此异常。我尝试调整 C3p0 属性,但它似乎不起作用。

以下是 C3p0 相关设置:

<property name="hibernate.c3p0.acquire_increment">2</property>
<property name="hibernate.c3p0.idle_test_period">60</property><!-- in seconds -->
<property name="hibernate.c3p0.min_size">2</property>
<property name="hibernate.c3p0.max_size">10</property>
<property name="hibernate.c3p0.max_statements">0</property>
<property name="hibernate.c3p0.timeout">180</property>
<property name="hibernate.c3p0.preferredTestQuery">select 1</property>

连接网址如下所示:

jdbc:mysql://<DB endpoint>?autoReconnect=true&useUniCode=true&characterEncoding=UTF-8&useSSL=true&requireSSL=true&verifyServerCertificate=false

堆栈跟踪是:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
Last packet sent to the server was 1549998 ms ago.

Caused by: javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLException: java.net.SocketException: 
Connection reset

我需要调整 MySQL 系统变量吗?任何指针我们如何避免这个异常?

谢谢吉滕德拉

4

2 回答 2

3

听起来您的池中有一些连接并且只使用其中的一部分。其中一些只是等待使用,然后变得陈旧(连接由于某种原因被重置 - 例如数据库端的一些超时)。然后,当您尝试使用它们时,您会遇到异常。

通常有几个选项可以解决这个问题,例如,您可以在从池中检索连接之前测试连接 (hibernate.c3p0.testConnectionOnCheckout)

您还可以定期检查池中的连接状态和/或检查签入时的连接。见http://www.mchange.com/projects/c3p0/#configuring_connection_testing

如果它没有帮助 - 整个堆栈跟踪可能很有用。

于 2012-09-28T08:27:04.750 回答
3

hibernate.c3p0.idle_test_period -- 或 c3p0.idleConnectionTestPeriod 将仅在连接空闲 60 秒时每 60 秒测试一次。如果你的应用非常活跃,它不会闲置这么久。c3p0 尝试注意到应用程序何时收到异常意味着连接应该无效,但这取决于异常的 SQLState,这在数据库/JDBC 驱动程序之间不一致并且不完全可靠。死连接很少能在多轮签入/签出后幸存下来,但在您的设置下,它可能会发生。

最简单的解决方案是将 c3p0.testConnectionOnCheckin 添加到您的配置中。这确保了无论连接是忙还是闲,连接都将在被允许进入池之前进行测试,而不会产生结帐测试的同步开销。

请看http://www.mchange.com/projects/c3p0/#configuring_connection_testing

还请验证您设置的配置参数是否正在进入底层连接池。c3p0 在池初始化时将其配置转储到您的 INFO 级别的日志中:检查您的日志以验证您的设置是否与您认为的一样。(或者,您可以在应用程序通过 jmx 运行时检查池。)

祝你好运!

于 2012-09-28T09:18:32.510 回答