Java 连接到 Amazon RDS Oracle 实例时如何处理“从读取调用中得到减一”错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19660336/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to approach a "Got minus one from a read call" error when connecting to an Amazon RDS Oracle instance
提问by Robert H
I'm running Oracle 11GR2 on an Amazon RDS instance. occasionally I get an IO Error: Got minus one from a read call
when making a call to DriverManager.getConnection(getUrl())
and I'm not sure why. Other applications work correctly.
我在 Amazon RDS 实例上运行 Oracle 11GR2。有时我IO Error: Got minus one from a read call
在打电话时会收到一个DriverManager.getConnection(getUrl())
,我不知道为什么。其他应用程序正常工作。
To further confuse things, the error will correct itself on occasion (following next iteration of the program).
更令人困惑的是,错误有时会自行纠正(在程序的下一次迭代之后)。
How should I approach a "Got minus one from a read call" error?
我应该如何处理“从读取调用中得到减一”错误?
Full stack trace:
完整的堆栈跟踪:
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 line 44: setConn(DriverManager.getConnection(getUrl()));
Database.java 第 44 行: setConn(DriverManager.getConnection(getUrl()));
Other info:
其他信息:
- I thought it was a bad JDBC url, but it does work, sometimes for days on end before failing.
- Amazon RDS is a managed instance and configuration changes may not be possible
- I am using ojdbc6.jar for connectivity
- 我认为这是一个错误的 JDBC url,但它确实有效,有时在失败之前连续几天。
- Amazon RDS 是托管实例,可能无法更改配置
- 我正在使用 ojdbc6.jar 进行连接
采纳答案by Stephen C
The immediate cause of the problem is that the JDBC driver has attempted to read from a network Socket that has been closed by "the other end".
问题的直接原因是 JDBC 驱动程序试图从已被“另一端”关闭的网络 Socket 中读取。
This could be due to a few things:
这可能是由于以下几点:
If the remote server has been configured (e.g. in the "SQLNET.ora" file) to not accept connections from your IP.
If the JDBC url is incorrect, you could be attempting to connect to something that isn't a database.
If there are too many open connections to the database service, it could refuse new connections.
如果远程服务器已配置(例如在“SQLNET.ora”文件中)不接受来自您 IP 的连接。
如果 JDBC url 不正确,您可能正在尝试连接到不是数据库的东西。
如果与数据库服务的打开连接过多,它可能会拒绝新连接。
Given the symptoms, I think the "too many connections" scenario is the most likely. That suggests that your application is leaking connections; i.e. creating connections and then failing to (always) close them.
鉴于这些症状,我认为“连接过多”的情况最有可能。这表明您的应用程序正在泄漏连接;即创建连接,然后未能(总是)关闭它们。
回答by Stelios Adamantidis
I would like to augment to Stephen C's answer, my case was on the first dot. So since we have DHCP to allocate IP addresses in the company, DHCP changed my machine's address without of course asking neither me nor Oracle. So out of the blue oracle refused to do anything and gave the minus one dreaded exception. So if you want to workaround this once and for ever, and since TCP.INVITED_NODES of SQLNET.ora file does not accept wildcards as stated here, you can add you machine's hostname instead of the IP address.
我想补充斯蒂芬 C 的回答,我的情况在第一个点上。所以既然我们有DHCP来分配公司的IP地址,DHCP就改变了我机器的地址,当然既不问我也不问Oracle。因此,出乎意料的 oracle 拒绝做任何事情,并给出了一个可怕的例外。因此,如果您想一劳永逸地解决此问题,并且由于 SQLNET.ora 文件的 TCP.INVITED_NODES 不接受此处所述的通配符,您可以添加您机器的主机名而不是 IP 地址。
回答by Arnab Sarkar
We faced the same issue and fixed it. Below is the reason and solution.
我们遇到了同样的问题并修复了它。下面是原因和解决方法。
Problem
问题
When the connection pool mechanism is used, the application server (in our case, it is JBOSS) creates connections according to the min-connection
parameter. If you have 10 applications running, and each has a min-connection
of 10, then a total of 100 sessions will be created in the database. Also, in every database, there is a max-session
parameter, if your total number of connections crosses that border, then you will get Got minus one from a read call
.
当使用连接池机制时,应用服务器(在我们的例子中是JBOSS)根据min-connection
参数创建连接。如果您有 10 个应用程序在运行,并且每个应用程序都有 10min-connection
个,那么将在数据库中创建总共 100 个会话。此外,在每个数据库中,都有一个max-session
参数,如果您的连接总数跨越该边界,那么您将获得Got minus one from a read call
.
FYI: Use the query below to see your total number of sessions:
仅供参考:使用下面的查询来查看您的会话总数:
SELECT username, count(username) FROM v$session
WHERE username IS NOT NULL group by username
Solution: With the help of our DBA, we increased that max-session
parameter, so that all our application min-connection
can accommodate.
解决方案:在我们的 DBA 的帮助下,我们增加了该max-session
参数,以便我们所有的应用程序min-connection
都可以容纳。