添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

今天早上遇到一个问题,是总部的开发发来的,

Cause:java.sql.SQLRecoverableException:无法从套接字读取更多的数据

java.sql.SQLRecoverableException: No more data to read from socket

首先要说明的是这个错误并不是JDBC或者是Oracle 的问题,而属于通信问题

在Oracle 11g环境中出现这个问题是BUG的概率还是比较大的。

提示,用客户端(plsql、Navicat)可以查询

但是在程序里查询,会出现以上的问题,偶尔一两次会成功,但是后续就会出现报错

其实这个问题还没有完全解决:

为什么使用客户端查询没有任何问题,使用程序会有问题?

我认为驱动的问题可能性更大一点

在网上查询相关为问题,一般都是说是以下两个原因:

1、驱动版本问题

2、查询的sql存在子查询

对于这俩问题,分别进行排查

1、我们的数据库是Oracle 11201,但是因为之前安全部门扫描,监听存在漏洞,于是使用的是

Oracle 11201 database + 11204的监听

对方开发换了不同的驱动,说同样存在这个问题

但是我还是有点怀疑,也有可能是因为没有真正的更换成功

2、针对sql存在子查询的问题

因为考虑数据安全,单独建立了一个用户A,而视图是基于B用户的,

所以就在A用户下建立了一个同名的同义词来访问。

对应查询里面确实有包含子查询,于是我在A用户下建立了一个表,该表的数据均来自原来的视图

对方的开发访问说前两次正常,后面还是异常。

在这里我就有点疑惑了,于是又做了以下操作,

1、Enable Dead Connection Detection (DCD):

a. Edit $ORACLE_HOME/network/admin/sqlnet.ora in the server side

b. Set SQLNET.EXPIRE_TIME=10

2、Set ENABLE=BROKEN Clause in the JDBC connection string.

For example: jdbc:oracle:thin:@(DESCRIPTION=(ENABLE=BROKEN)(ADDRESS=(PROTOCOL=tcp)(PORT=<port>)(HOST=<host>))(CONNECT_DATA=(SID=<sid>))). If a datasource is used, then this connection string should be modified in the datasource definition.

In this case, if the JDBC connection string in the datasource is:

jdbc:oracle:thin:@<ip address>:<port>:<sid>

then, it should be modified to be:

jdbc:oracle:thin:@(DESCRIPTION=(ENABLE=BROKEN)(ADDRESS=(PROTOCOL=tcp)(PORT=1521)(HOST=<host>))(CONNECT_DATA=(SID=<sid>))

以上来自文档Doc ID 2301162.1

经过以上调节之后,对方测试直接发来一个报错:

Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is java.sql.SQLRecoverableException: IO 错误: NL Exception was generated

这次干脆都没连接到数据库。

后来沟通说,因为安全等原因,他们在本地是不能直接访问我们的生产数据库的,但是因为开发原因,需要

连接上该库进行测试,于是让运维给设置的代理,地址变成a.a.a.a,端口为1111,原来的地址为b.b.b.b 端口为1521

到这里就比较复杂了,具体是因为那里的原因还是不太确定,但是可以确认的是,不是数据库方面的原因,

我更多认为是网络的原因。

因为并不是一直连接不了数据库,而是经常前两次能连接上进行查询,后面就不行了。

但是上线之后这个问题大概率不会再发生,因为代码可以直连我们的数据库来进行查询。

而现在是因为没有走正常的路线(使用代理)导致频繁出现这个问题,其实我对此不能提供更多帮助了。

解决的办法可以使用:

1、自己在本地造一些数据来进行测试,保证功能没有问题即可

2、开发完成之后发布到测试环境来进行测试,测试库直连我们数据库,这样可以省去中间很多过程,减少问题的发生。

之所以到了这里我提供不了什么帮助,主要是因为这个过程涉及到了代理,代理的配置,中间网络的设置等等(

因为集团的网络比较复杂,而且专人专管,我们和对方分隔两地,我不知道我提供的方案对方是否正确的完成测试等等)

以上是在处理这个问题时的思路,在遇到问题时,首先从全局来确认当前的情况,不要以为所有都是正确的,比如再次确认所有的基础信息,比如连接串是否正确,报错的具体内容等等,然后再做下一步的排查。

参考文档:

​https://blog.csdn.net/weixin_44455388/article/details/108343020​

​https://blog.csdn.net/qq_37749959/article/details/118303841​

Connections Fail with Java.sql.SQLException: OALL8 Is In An Inconsistent State and java.sql.SQLRecoverableException: No more data to read from socket (Doc ID 2301162.1)

​http://www.dba-oracle.com/t_no_more_data_to_read_from_socket.htm​

​https://www.cnblogs.com/zhjh256/p/9260018.html​