SQLException:oracle 中的协议冲突

Posted

技术标签:

【中文标题】SQLException:oracle 中的协议冲突【英文标题】:SQLException: Protocol Violation in oracle 【发布时间】:2015-06-05 00:40:00 【问题描述】:

我收到“违反协议”。 我有一个在 RedHat Linux 上运行的应用程序。数据库和应用程序共同驻留在机器上。

使用的 Oracle 版本:Oracle 11g R2 (11.2.0.3.0) 使用的 JDBC 驱动程序:12.1.0.1 使用的 Java:jdk1.7.0.65 32 位

我遇到过许多论坛,其中指出此错误是驱动程序问题,但在所有这些论坛中,使用的 oracle 版本更高,驱动程序版本更旧,更改驱动程序解决了问题。但在我的情况下Oracle版本较低,但驱动版本较高。那么,在这种情况下,驱动的更高版本会不会有问题?

此外,当达到 DB 上的最大连接数时,也会出现这种协议违规?

错误信息:

java.sql.SQLException:协议违规:[72] 在 oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:464) 在 oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192) 在 oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:531) 在 oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:207) 在 oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:884) 在 oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:1167) 在 oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1289) 在 oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3584) 在 oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3628) 在 oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1493)

【问题讨论】:

是不是因为你的用户密码过期了? @kucing_terbang 不,用户的密码没有过期。 我们需要查看完整的错误消息,而不仅仅是两个词的摘要。 ***.com/questions/4685021/… 【参考方案1】:

在我的例子中,当我们尝试使用 ojdbc 驱动程序从另一个数据源中针对 db 链接提取数据时发生这种情况,我们没有连接到直接数据源。一旦我们通过直接连接而不是使用 db 链接进行连接,问题就会停止出现。 我注意到的另一件事是,当我们尝试从包含中文/日文字符的列中提取数据时,该问题以一致的方式发生。 最后,分块提取数据也是一个合适的解决方案。HTH

【讨论】:

【参考方案2】:

增加堆空间!

我有这个确切的错误随机出现。

应用程序内存不足,OutOfMemory 错误由于代码中的逻辑而丢失,导致抛出不相关的异常。

应用程序不应处理 throwable 和错误的原因之一。

【讨论】:

有同样的问题。监控工具极大地帮助解决此类错误...【参考方案3】:

ojdbc7.jar 中修复的问题 - 版本 12.1.0.2(您可以在 jar 的 META-INF 文件中查看版本)

【讨论】:

如果你使用 clob 则有效:***.com/questions/22785120/…【参考方案4】:

这通常表示损坏的 tcp/ip 流量。这可能是由于注入的流量或丢弃的数据包造成的。执行ifconfig 以查看您的任何网络接口是否受到异常大量丢弃数据包的影响。为避免出现问题,当您指出数据库和 java 程序在同一台机器上运行时,请尝试使用环回接口 127.0.0.1 (localhost),而不是使用外部 IP 连接到数据库,或者只是为了测试。

没有对此进行进一步研究,但我想当驱动程序和数据库版本相距太远时也会发生这种情况。让驱动程序与已安装的 oracle 匹配应该不会太难。

【讨论】:

【参考方案5】:

在我的例子中,使用 PreparedStatement 的 getGeneratedKeys() 来获取当前序列值导致了协议违规异常。替换为从序列中获取序列当前值,如下:

String curSeqValQuery = "SELECT seq_name.CURRVAL FROM DUAL";
...
statement = con.prepareStatement(curSeqValQuery);
resultSet = (OracleResultSet) statement.executeQuery();
...

解决了这个问题。

【讨论】:

【参考方案6】:

可能只是连接被感染或无效。如果您的 JDBC 连接来自连接池,请始终确保在保留时测试连接。

【讨论】:

【参考方案7】:

这样的错误表明 JDBC 瘦驱动程序中存在错误,无法理解服务器在线路(套接字)上返回的内容。

您始终可以尝试使用最新的 JDBC 瘦驱动程序,希望能解决该错误。截至今天,最新的是 12.1.0.2。

如果这没有帮助,那么您需要联系 Oracle 支持。您将被要求的第一件事是提供发生此错误的连接的 sqlnet 跟踪。这将帮助 Oracle 工程师了解故障发生时网络上发生的情况。

要打开 sqlnet 跟踪,请编辑服务器上的 sqlnet.ora 文件并添加

TRACE_LEVEL_SERVER = 16

这将为您的跟踪控制器(在服务器上)中的每个连接添加一个跟踪文件。不要在生产系统上执行此操作,因为它会显着降低系统速度并生成大量跟踪。

祝你好运。

【讨论】:

以上是关于SQLException:oracle 中的协议冲突的主要内容,如果未能解决你的问题,请参考以下文章

Oracle DB:java.sql.SQLException:关闭连接

Oracle: java.sql.SQLException: ORA-01653 1024 错误 求分析

java.sql.SQLException:指定的 Oracle URL 无效错误

《MySQL冲冲冲》MySQL vs Oracle,你选谁?

Spring PreparedStatementCallback; SQL 无效列类型 Oracle 的未分类 SQLException

Oracle java.sql.SQLException: 数字溢出