Amazon RDSインスタンスでOracle 11GR2を実行しています。時折、DriverManager.getConnection(getUrl())
を呼び出すときにIO Error: Got minus one from a read call
を受け取りますが、その理由はわかりません。他のアプリケーションは正常に動作します。
さらに混乱させるために、エラーは時々修正されます(プログラムの次の反復後)。
「Got-read read from one」のエラーにどのようにアプローチすればよいですか?
完全なスタックトレース:
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ドライバーが「もう一方の端」によって閉じられたネットワークソケットから読み取ろうとしたことです。
これはいくつかの原因による可能性があります。
IPからの接続を受け入れないようにリモートサーバーが構成されている場合(「SQLNET.ora」ファイルなど)。
JDBC URLが正しくない場合、データベースではないものに接続しようとしている可能性があります。
データベースサービスへの開いている接続が多すぎる場合、新しい接続を拒否する可能性があります。
症状を考えると、「接続が多すぎる」シナリオが最も可能性が高いと思います。これは、アプリケーションが接続をリークしていることを示しています。つまり、接続を作成してから、(常に)接続に失敗します。
同じ問題に直面し、修正しました。以下が理由と解決策です。
問題
接続プールメカニズムを介してデータベース接続を作成すると、アプリサーバー(この場合はJBOSS)がmin-connectionパラメーターで述べたように接続を作成します。 10個のアプリケーションを実行していて、それぞれのアプリケーションのmin接続が10である場合、合計100個のセッションがデータベースに作成されます。また、すべてのデータベースにmax-sessionパラメーターがあります。合計接続がその境界を超えると、「読み取り呼び出しから1を引いた」というメッセージが表示されます。
SELECT username, count(username) FROM v$session
WHERE username IS NOT NULL group by username
解決策:DBAの助けを借りて、すべてのアプリケーションの最小接続に対応できるように、その最大セッションを増やしました。
私はスティーブンCの答えを補強したいと思います。私の場合は最初の点についてでした。したがって、社内にIPアドレスを割り当てるDHCPがあるため、DHCPはもちろん、私にもOracleにも尋ねることなく、マシンのアドレスを変更しました。だから、オラクルは何もすることを拒否し、マイナス1の恐ろしい例外を与えました。したがって、これを永遠に回避したい場合、およびSQLNET.oraファイルのTCP.INVITED_NODESが here のようにワイルドカードを受け入れないため、IPアドレスの代わりにマシンのホスト名を追加できます。