【问题标题】:Hibernate for Java web applicationJava Web 应用程序的休眠
【发布时间】:2013-02-06 07:40:38
【问题描述】:

我正在使用带有 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 造成了连接设置问题?

【问题讨论】:

  • 你的意思是 JPA,而不是 OpenJPA?
  • 我正在为 JPA 使用 OpenJPA jar。 OpenJPA 是 Apache Software Foundation 对 JPA 的实现。
  • 我知道 OpenJPA 是什么,这就是我问这个问题的原因。在您的 persistence.xml 中,很明显您使用的是 Hibernate,而不是 OpenJPA。

标签: hibernate jpa


【解决方案1】:

就好像连接池有一个连接的引用,但是当它真正尝试使用它时——发现连接是无效的! :-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

【讨论】:

  • 感谢您的回复。我知道为什么会出现错误,但我很困惑,因为即使添加了所有必需的设置,它仍然给我超时错误。我解决了添加"debugUnreturnedConnectionStackTraces""hibernate.c3p0.idle_test_period" 的错误。这两个设置转储了我的应用程序中连接未释放的堆栈日志。一旦这个问题得到修复,应用程序现在不会给出超时错误。
猜你喜欢
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
  • 2012-07-08
  • 1970-01-01
  • 2011-12-20
  • 1970-01-01
  • 1970-01-01
  • 2013-12-09
相关资源
最近更新 更多