连接到Amazon RDS Oracle实例时,如何处理“从读取调用中减去一个”错误

时间:2013-10-29 13:59:56

标签: java oracle

我在Amazon RDS实例上运行Oracle 11GR2。偶尔我在拨打IO Error: Got minus one from a read call时会收到DriverManager.getConnection(getUrl()),但我不确定原因。其他应用程序正常工作

为了进一步混淆事物,错误会偶尔纠正(在程序的下一次迭代之后)。

我应该如何处理“读取呼叫中的减去”错误?

完整堆栈跟踪:

java.sql.SQLRecoverableException: IO Error: Got minus one from a read call
    at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:489)
    at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:553)
    at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:254)
    at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32)
    at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:528)
    at java.sql.DriverManager.getConnection(DriverManager.java:579)
    at java.sql.DriverManager.getConnection(DriverManager.java:243)
    at com.cwd.facile.db.Database.<init>(Database.java:44)
    at com.cwd.facile.ns.NetSuiteRequestBased.<init>(NetSuiteRequestBased.java:29)
    at com.cwd.facile.ns.CommonOperations.isInventoryItem(CommonOperations.java:205)
    at com.cwd.facile.ns.CommonOperations.findItemIdByName(CommonOperations.java:188)
    at com.cwd.facile.ns.CommonOperations.createSalesOrder(CommonOperations.java:970)
    at com.cwd.facile.Main.main(Main.java:47)
Caused by: oracle.net.ns.NetException: Got minus one from a read call
    at oracle.net.ns.Packet.receive(Packet.java:311)
    at oracle.net.ns.NSProtocol.connect(NSProtocol.java:300)
    at oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:1140)
    at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:340)
    ... 12 more

Database.java第44行:setConn(DriverManager.getConnection(getUrl()));

其他信息:

  • 我认为这是一个糟糕的JDBC网址,但它确实有效,有时连续几天才会失败。
  • Amazon RDS是托管实例,可能无法更改配置
  • 我正在使用ojdbc6.jar进行连接

5 个答案:

答案 0 :(得分:77)

问题的直接原因是JDBC驱动程序试图从已被“另一端”关闭的网络套接字读取。

这可能是由于以下几点:

  • 如果远程服务器已配置(例如在“SQLNET.ora”文件中),则不接受来自IP的连接。

  • 如果JDBC网址不正确,您可能会尝试连接到非数据库的网址。

  • 如果与数据库服务的连接太多,则可能会拒绝新连接。

鉴于这些症状,我认为最有可能出现“连接太多”的情况。这表明您的应用程序正在泄漏连接;即创建连接然后无法(始终)关闭它们。

答案 1 :(得分:10)

我们面临同样的问题并修复了。以下是原因和解决方案。

<强>问题

当我们通过连接池机制创建数据库连接时,应用服务器(在我们的例子中是JBOSS)创建连接,如min-connection参数中所述。如果您有10个应用程序正在运行,并且每个应用程序的最小连接数为10,那么将在数据库中创建总共100个会话。同样在每个数据库中都有一个max-session参数,如果你的总连接越过那个边界,那么你会得到“从读取呼叫中减去一个” 仅供参考:使用以下查询查看您的总会话

SELECT username, count(username) FROM v$session 
WHERE username IS NOT NULL group by username

解决方案:在我们的DBA的帮助下,我们增加了max-session,以便我们所有的应用程序最小连接都可以容纳。

答案 2 :(得分:1)

我想补充斯蒂芬C的答案,我的案子是第一个点。因为我们有DHCP在公司分配IP地址,所以DHCP改变了我的机器地址,当然不要求我和Oracle。因此,蓝色的甲骨文拒绝做任何事情并给出了一个可怕的例外。因此,如果您希望一劳永逸地解决此问题,并且由于SQLNET.ora文件的TCP.INVITED_NODES不接受声明为here的通配符,您可以添加计算机的主机名而不是IP地址。

答案 3 :(得分:1)

尽管我已将端口发布到主机选项“ -p 1521:1521”,但我在docker中使用oracle数据库却收到此错误消息。我正在使用使用IP地址127.0.0.1的jdbc url,我将其更改为主机的真实IP地址,然后一切正常。

答案 4 :(得分:0)

在我的情况下,我遇到了同样的异常,因为在数据库中不存在我在应用程序中配置的用户,因此创建该用户并授予所需的权限即可解决该问题。