【问题标题】:How to handle Broken pipe error with Spring, (JPA) Hibernate, MySQL如何使用 Spring、(JPA) Hibernate、MySQL 处理 Broken pipe 错误
【发布时间】:2014-09-12 05:57:08
【问题描述】:

我有一个使用 Spring JPA (Hibernate) 和 MySQL 在 Tomcat 中运行的 Web 应用程序。 经过一段时间的不活动后,我总是得到这个异常:

Caused by: javax.persistence.PersistenceException: org.hibernate.TransactionException: JDBC begin transaction failed: 
        at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1763) ~[hibernate-entitymanager-4.3.5.Final.jar:4.3.5.Final]
        at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677) ~[hibernate-entitymanager-4.3.5.Final.jar:4.3.5.Final]
        at org.hibernate.jpa.spi.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:1771) ~[hibernate-entitymanager-4.3.5.Final.jar:4.3.5.Final]
        at org.hibernate.jpa.internal.TransactionImpl.begin(TransactionImpl.java:64) ~[hibernate-entitymanager-4.3.5.Final.jar:4.3.5.Final]
        at org.springframework.orm.jpa.DefaultJpaDialect.beginTransaction(DefaultJpaDialect.java:67) ~[spring-orm-4.0.3.RELEASE.jar:4.0.3.RELEASE]
        at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:380) ~[spring-orm-4.0.3.RELEASE.jar:4.0.3.RELEASE]
        ... 38 common frames omitted
Caused by: org.hibernate.TransactionException: JDBC begin transaction failed: 
        at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:76) ~[hibernate-core-4.3.5.Final.jar:4.3.5.Final]
        at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:162) ~[hibernate-core-4.3.5.Final.jar:4.3.5.Final]
        at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1435) ~[hibernate-core-4.3.5.Final.jar:4.3.5.Final]
        at org.hibernate.jpa.internal.TransactionImpl.begin(TransactionImpl.java:61) ~[hibernate-entitymanager-4.3.5.Final.jar:4.3.5.Final]
        ... 40 common frames omitted
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 48,764,262 milliseconds ago.  The last packet sent successfully to the server wa
s 48,764,262 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.
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.7.0_55]
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) ~[na:1.7.0_55]
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.7.0_55]
        at java.lang.reflect.Constructor.newInstance(Constructor.java:526) ~[na:1.7.0_55]
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:409) ~[mysql-connector-java-5.1.30.jar:na]
        at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1127) ~[mysql-connector-java-5.1.30.jar:na]
        at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3983) ~[mysql-connector-java-5.1.30.jar:na]
        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2596) ~[mysql-connector-java-5.1.30.jar:na]
        at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2776) ~[mysql-connector-java-5.1.30.jar:na]
        at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2832) ~[mysql-connector-java-5.1.30.jar:na]
        at com.mysql.jdbc.ConnectionImpl.setAutoCommit(ConnectionImpl.java:5357) ~[mysql-connector-java-5.1.30.jar:na]
        at org.apache.tomcat.dbcp.dbcp.DelegatingConnection.setAutoCommit(DelegatingConnection.java:373) ~[commons-dbcp-eap6.jar:na]
        at org.apache.tomcat.dbcp.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.setAutoCommit(PoolingDataSource.java:330) ~[commons-dbcp-eap6.jar:na]
        at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:72) ~[hibernate-core-4.3.5.Final.jar:4.3.5.Final]
        ... 43 common frames omitted
Caused by: java.net.SocketException: Broken pipe
        at java.net.SocketOutputStream.socketWrite0(Native Method) ~[na:1.7.0_55]
        at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:113) ~[na:1.7.0_55]
        at java.net.SocketOutputStream.write(SocketOutputStream.java:159) ~[na:1.7.0_55]
        at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82) ~[na:1.7.0_55]
        at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140) ~[na:1.7.0_55]
        at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3964) ~[mysql-connector-java-5.1.30.jar:na]
        ... 50 common frames omitted

现在,我知道这与 MySQL 在 8 小时后关闭连接和 Hibernate 尝试使用此连接有关,并且我的连接池可能没有正确配置或根本没有配置,但我不知道该怎么做.

我什至在 mysql url 连接配置中添加了autoReconnect=true,但它没有帮助。

这是 Tomcat 配置的 server.xml 中的内容。

    <Resource name="jdbc/mysqldb" auth="Container"
      type="javax.sql.DataSource"
    ...  
url="jdbc:mysql://${env.OPENSHIFT_MYSQL_DB_HOST}:${env.OPENSHIFT_MYSQL_DB_PORT}/${env.OPENSHIFT_APP_NAME}?autoReconnect=true"/>

应该在哪里配置什么才能让它工作?

【问题讨论】:

  • 您能否向我们提供您在导致异常的代码中究竟做了什么??

标签: java mysql spring hibernate jpa


【解决方案1】:

尝试在休眠配置中做这样的事情:

<property name="connection.autoReconnect"> true </ property>
<property name="connection.autoReconnectForPools"> true </ property>
<property name="connection.is-connection-validation-required"> true </ property>

【讨论】:

    【解决方案2】:

    尝试添加testOnBorrow="true" and validationQuery="SELECT 1" validationInterval="60000" 当数据库服务器终止连接时会发生这种情况。添加这些参数后,连接池将验证连接,然后再将其提供给应用程序。如果它无效,连接将被丢弃并创建一个新的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-12
      • 2016-11-04
      • 2011-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-18
      相关资源
      最近更新 更多