0

我正在使用带有 c3p0 的 Hibernate(用于连接池)。

我已经使用 persistence.xml 文件设置了我的连接详细信息。这是我的 persistence.xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence persistence_2_0.xsd">
<persistence-unit name="LBSV1.0" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <class>xx.dataobject.CompanyDO</class>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>
        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
        <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
        <property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
        <property name="hibernate.connection.url" value="jdbc:mysql://xx.xx.xx.xx:xxxx/lbs?autoReconnect=true"/>
        <property name="hibernate.connection.username" value="username"/>
        <property name="hibernate.connection.password" value="password"/>
        <property name="hibernate.generate_statistics" value="true"/>
        <property name="hibernate.cache.provider_class" value="org.hibernate.cache.OSCacheProvider"/>
        <property name="hibernate.cache.use_second_level_cache" value="true"/>
        <property name="hibernate.show_sql" value="true"/>
        <property name="hibernate.format_sql" value="true"/>
        <property name="hibernate.c3p0.min_size" value="5"/>
        <property name="hibernate.c3p0.max_size" value="20"/>
        <property name="hibernate.c3p0.timeout" value="1800"/>
        <property name="hibernate.c3p0.max_statements" value="50"/>
        <property name="hibernate.c3p0.idle_test_period" value="300"/>
        <property name="c3p0.preferredTestQuery" value="select * from status"/>
        <property name="c3p0.testConnectionOnCheckout" value="true"/>
        <property name="c3p0.debugUnreturnedConnectionStackTraces" value="true"/>

    </properties>
</persistence-unit>

该应用程序运行良好。应用程序正在获取、插入、删除和更新数据。但是如果应用程序空闲超过 8 小时,那么我们会收到以下错误:

05 Feb 2013 19:40:25 49640738 [http-8080-8] ERROR root  - [SubscriberDataManager]****** Enable to get Subscriber Details due to : The last packet successfully received from the server was 49,165,385 milliseconds ago.  The last packet sent successfully to the server was 49,165,386 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.

在 URL 中添加了建议的“autoReconnect=true”。我还搜索了连接超时问题并在“persistence.xml”文件中添加了所需的属性值,但错误仍然存​​在。

这是 c3p0 的初始化日志条目:

06 Feb 2013 12:00:56 149355789 [http-8080-1] INFO  com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource  - Initializing c3p0 pool... com.mchange.v2.c3p0.PoolBackedDataSource@9263d39c [ connectionPoolDataSource -> com.mchange.v2.c3p0.WrapperConnectionPoolDataSource@77f9bf08 [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, debugUnreturnedConnectionStackTraces -> true, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> z8kfsx8s1cc19kywfwqwq|1bdcbb2, idleConnectionTestPeriod -> 300, initialPoolSize -> 5, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 1800, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 20, maxStatements -> 50, maxStatementsPerConnection -> 0, minPoolSize -> 5, nestedDataSource -> com.mchange.v2.c3p0.DriverManagerDataSource@7a7a7ef8 [ description -> null, driverClass -> null, factoryClassLocation -> null, identityToken -> z8kfsx8s1cc19kywfwqwq|1b8737f, jdbcUrl -> jdbc:mysql://**.**.**.**:****/lbs?autoReconnect=true, properties -> {user=******, password=******, autocommit=true, release_mode=auto} ], preferredTestQuery -> select * from status, propertyCycle -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> true, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false; userOverrides: {} ], dataSourceName -> null, factoryClassLocation -> null, identityToken -> z8kfsx8s1cc19kywfwqwq|68097d, numHelperThreads -> 3 ]

谁能告诉我

  1. 我在 persistence.xml 文件中的设置有什么问题?

  2. 或者 Hibernate 是否与连接设置产生了问题?

4

1 回答 1

0

就好像连接池有一个连接的引用,但是当它实际尝试使用它时 - 发现连接无效!:-O

所以我认为数据库正在超时连接,而连接池对此一无所知。

您问题中的一段文字可能表明答案:

"is longer than the server configured value of 'wait_timeout'"

因此,我认为您需要查看 MySql 中配置的 wait_timeout 设置。请记住,您正在配置连接池大小(例如 hibernate.c3p0.max_size=20),但 MySql 数据库具有相同的设置。所以(好吧,实际上不确定 MySql 中是否有等价物——这里只是原则性地谈论)如果你的 MySql 数据库配置为只允许 10 个连接——那么连接池将永远不会增长到你配置的最大大小。

您可以在您使用的 MySql .cnf 文件中找到“wait_timeout”设置。

在 Linux 下:

cat /etc/mysql/my.cnf | grep -i wait

默认值为 28800(8 小时) - 因此您需要增加它。让我们考虑一下。假设有人工作到下午 5 点,第二天早上 8 点又回来工作——那已经是 15 个小时了。因此,这可以为您提供一个关于您需要将其设置为什么值的指南。

除了 - 是的,向应用程序抛出错误真的很糟糕......但是,是的,我认为增加wait_timeout是一种好习惯。即使没有抛出错误:假设你有 100 万人;) 早上 8 点上班......实施很可能真的很难在几分钟内获得一百万个新连接(昂贵的操作)所以在在涉及许多连接的情况下,不能允许连接过期。

当我遇到同样的问题时,我对此做了一些进一步的说明(但与您的设置无关,但可能对其他人有用)

Database connections are managed by c3p0. The database must not prematurely timeout connections managed by c3p0.
    (a) "Check the system configuration on your database. MySQL has a wait_timeout setting which will close the connections idle over a period of time. If your idle_test_period and timeout are greater than MySQL wait_timeout (28800 seconds by default), your unused connections will have chance to be reset by MySQL server before tested or timed out by C3p0."
    (b) "Make sure the value here <property name="hibernate.c3p0.idle_test_period">100</property> which is 100 is less than the wait_timeout set for mysql (by default it is 8 hrs
于 2013-05-19T10:10:27.790 回答