今天早上遇到一个问题,是总部的开发发来的,
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