Java 使用EclipseLink的特定SQL上的MySQL通信链接失败

Java 使用EclipseLink的特定SQL上的MySQL通信链接失败,java,mysql,jpa,eclipselink,Java,Mysql,Jpa,Eclipselink,EclipseLink 2.5.1,Tomcat 7,MySQL JDBC驱动程序5.1.31。我有一个特定的SELECT语句,当由我的webapp执行时,它始终会产生comm link故障(在mysql客户端中运行完全相同的SELECT工作正常,结果大约在800毫秒后返回)。我在MySQL上修改了超时设置,没有区别 javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence

EclipseLink 2.5.1,Tomcat 7,MySQL JDBC驱动程序5.1.31。我有一个特定的SELECT语句,当由我的webapp执行时,它始终会产生comm link故障(在mysql客户端中运行完全相同的SELECT工作正常,结果大约在800毫秒后返回)。我在MySQL上修改了超时设置,没有区别

javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet successfully received from the server was 912 milliseconds ago.  The last packet sent successfully to the server was 901 milliseconds ago.
Error Code: 0
Call: SELECT ...

Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet successfully received from the server was 912 milliseconds ago.  The last packet sent successfully to the server was 901 milliseconds ago.
    at sun.reflect.GeneratedConstructorAccessor523.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
    at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1117)
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3567)
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3456)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3997)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2468)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2629)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2719)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
    at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2318)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeSelect(DatabaseAccessor.java:1007)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:642)
    ... 35 more
Caused by: java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(SocketInputStream.java:152)
MySQL服务器是本地的,下面是JNDI:

<Resource name="jdbc/my-mysql"
          auth="Container"
          type="javax.sql.DataSource"
          testWhileIdle="true"
          testOnBorrow="true"
          testOnReturn="false"
          validationQuery="SELECT 1"
          validationInterval="30000"
          maxActive="100"
          minIdle="10"
          maxWait="10000"
          initialSize="10"
          removeAbandonedTimeout="60"
          removeAbandoned="true"
          logAbandoned="true"
          minEvictableIdleTimeMillis="30000"
          username="my"
          password="my"
          driverClassName="com.mysql.jdbc.Driver"
          url="jdbc:mysql://localhost:3306/mydb?zeroDateTimeBehavior=convertToNull&amp;autoReconnect=true&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;socketTimeout=900&amp;autoReconnectForPools=true"/>

下面是persistence.xml:

<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 http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    <persistence-unit name="my-persistence-unit" transaction-type="RESOURCE_LOCAL">
        <validation-mode>NONE</validation-mode>
        <non-jta-data-source>java:comp/env/jdbc/my-mysql</non-jta-data-source>
        <properties>
            <property name="eclipselink.weaving" value="static"/>
            <property name="eclipselink.query-results-cache" value="true"/>
            <property name="eclipselink.connection-pool.initial" value="16" />
            <property name="eclipselink.connection-pool.min" value="64" />
            <property name="eclipselink.connection-pool.max" value="128" />
        </properties>
    </persistence-unit>
</persistence>

没有一个
java:comp/env/jdbc/mymymysql

问题似乎是socketTimeout=900的值对于测试环境中预计需要800毫秒的查询来说不够时间。此值导致套接字本身在查询返回之前超时。更改此值以使查询在系统和网络处于负载状态时完成所需的时间可以解决此问题。

是仅此查询还是应用程序中的其他查询?还请注意,如果您使用的是数据源,则不应使用eclipselink.connection-pool设置-它们用于配置eclipselink控制的连接池。其他查询也会间歇性失败。另一件有趣的事情是,部署在测试服务器上的同一个WAR可以很好地执行相同的SQL。在添加连接池设置之前,我间歇性地遇到同样的问题。。。无论如何,我都会尝试删除它们,看看会发生什么情况您在使用的JDBC连接上设置了参数,例如socketTimeout=900,这可能是导致问题的原因。连接的套接字将在900毫秒后超时,预计需要800毫秒的查询将非常接近这个时间。您可能希望删除此超时并再次测试。感谢您的指针,我们将重试!出于某种原因,我认为超时是以秒为单位设置的,而不是msI。我相信您使用了socketTimeout设置。请提交答案,我将欣然接受。谢谢抢手货非常感谢。