Reputation: 2165
EclipseLink 2.5.1, Tomcat 7, MySQL JDBC driver 5.1.31. I have a specific SELECT statement that consistently produces comm link failure when executed by my webapp (running exactly the same SELECT in mysql client works just fine, and results come back in about 800ms). I have fiddled around with timeout settings on MySQL, no difference.
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)
The MySQL server is local, here is 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&autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&socketTimeout=900&autoReconnectForPools=true"/>
and here is 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>
Upvotes: 1
Views: 2987
Reputation: 21145
The problem seems to be that the socketTimeout=900 value is not enough time for a query expected to take 800ms in the test environment. This value causes the socket itself to timeout before the query can return. Changing this value to give the query the time it needs to complete when the system and network are under load will resolve the issue.
Upvotes: 1