java - 奇怪的 SQLException - 无法检索事务只读状态服务器

标签 java mysql sql jdbc

我有一个 Quartz每 5 分钟在我的 MySQL 数据库中执行一次存储过程的作业,由于某种原因,三分之一的执行失败并给出了这个奇怪的异常。我已经搜索并搜索了此异常的含义,但找不到解决方案。这是完整的堆栈跟踪:

java.sql.SQLException: Could not retrieve transation read-only status server
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1078)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:975)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:920)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:951)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:941)
    at com.mysql.jdbc.ConnectionImpl.isReadOnly(ConnectionImpl.java:3939)
    at com.mysql.jdbc.ConnectionImpl.isReadOnly(ConnectionImpl.java:3910)
    at com.mysql.jdbc.PreparedStatement.checkReadOnlySafeStatement(PreparedStatement.java:1258)
    at com.mysql.jdbc.CallableStatement.checkReadOnlySafeStatement(CallableStatement.java:2656)
    at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1278)
    at com.mysql.jdbc.CallableStatement.execute(CallableStatement.java:920)
    at com.mchange.v2.c3p0.impl.NewProxyCallableStatement.execute(NewProxyCallableStatement.java:3044)
    at org.deadmandungeons.website.tasks.RankUpdateTask.execute(RankUpdateTask.java:30)
    at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
    at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet successfully received from the server was 1,198,219 milliseconds ago.  The last packet sent successfully to the server was 950,420 milliseconds ago.
    at sun.reflect.GeneratedConstructorAccessor43.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:1121)
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3673)
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3562)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4113)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2570)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2731)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2812)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2761)
    at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1612)
    at com.mysql.jdbc.ConnectionImpl.isReadOnly(ConnectionImpl.java:3933)
    ... 9 more
Caused by: java.net.SocketException: Connection timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(SocketInputStream.java:150)
    at java.net.SocketInputStream.read(SocketInputStream.java:121)
    at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:114)
    at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:161)
    at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:189)
    at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:3116)
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3573)
    ... 17 more

所以我认为它正在超时,因为它认为 MySQL 服务器处于只读状态? 这只发生在这个 quartz 作业中,而不是我与数据库通信的任何其他时间。这个执行当然是在另一个线程中发生的,但我认为这与它没有任何关系。 为什么它会认为服务器处于只读模式?

另外,我不认为“翻译”是一个词,所以就是这样......

最佳答案

很抱歉在旧帖子上发帖,

正如堆栈跟踪所说

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

这意味着 JDBC 和 DB 之间的链接已断开。根据您的观察,您说 3 个作业调用中有 1 个失败。

您每 5 分钟安排一次这些作业,并且根据跟踪,最后一次成功发送到服务器的消息大约在 15 分钟之前。

因此我怀疑

  1. 您的程序没有返回(等待某事)
  2. JDBC 连接已被防火墙/代理失效

看看如何管理连接会很有趣,根据日志,我看到你正在使用 c3p0。

您可以尝试设置 unreturnedConnectionTimeoutdebugUnreturnedConnectionStackTraces。这将使您更深入地了解需要很长时间的连接泄漏或数据库调用。

关于java - 奇怪的 SQLException - 无法检索事务只读状态服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21651671/

相关文章:

sql - 空数组作为 PostgreSQL 数组列默认值

java - 正则表达式提取范围内的数字

java - 抽象类数组

java - 为什么我无法播放音频文件

mysql - Laravel 4.0 按钮功能每日限制

mysql - 数据库中的一对一关系

java - Button.isEnabled() 返回 true,即使按钮在默认情况下处于禁用状态

PHP 和 Mysql - 如何让我的登录系统与我的数据库一起工作?

sql - 在存储过程中,是简单地查询数据还是构造一个查询然后执行它更好?为什么?

MySQL 查询 3 个表