Bir Amazon RDS örneğinde Oracle 11GR2 çalıştırıyorum. bazen IO Hatası alıyorum: DriverManager.getConnection(getUrl())
çağrısı yaparken bir okuma çağrısından eksi bir aldım ve nedeninden emin değilim. Diğer uygulamalar düzgün çalışıyor.
İşleri daha da karıştırmak için, hata zaman zaman kendini düzeltecektir (programın bir sonraki yinelemesini takiben).
**Bir "Okuma çağrısından eksi bir aldım" hatasına nasıl yaklaşmalıyım?
Tam yığın izi:
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 satır 44: setConn(DriverManager.getConnection(getUrl()));
Diğer bilgiler:
Sorunun ilk nedeni, JDBC sürücüsünün "diğer uç" tarafından kapatılmış bir ağ Soketinden okuma yapmaya çalışmasıdır.
Bunun birkaç nedeni olabilir:
Uzak sunucu IP adresinizden gelen bağlantıları kabul etmeyecek şekilde yapılandırılmışsa (örneğin "SQLNET.ora" dosyasında).
JDBC url'si yanlışsa, veritabanı olmayan bir şeye bağlanmaya çalışıyor olabilirsiniz.
Veritabanı hizmetine çok fazla açık bağlantı varsa, yeni bağlantıları reddedebilir.
Belirtiler göz önüne alındığında, "çok fazla bağlantı" senaryosunun en olası senaryo olduğunu düşünüyorum. Bu, uygulamanızın bağlantıları sızdırdığını, yani bağlantılar oluşturduğunu ve daha sonra bunları (her zaman) kapatamadığını gösterir.
Aynı sorunla karşılaştık ve düzelttik. Nedeni ve çözümü aşağıdadır.
Problem
Bağlantı havuzu mekanizması aracılığıyla bir veritabanı bağlantısı oluşturduğumuzda, uygulama sunucusu (bizim durumumuzda JBOSS) min-connection parametresinde belirtildiği gibi bağlantı oluşturur. Çalışan 10 uygulamanız varsa ve her birinin min-bağlantısı 10 ise, veritabanında toplam 100 oturum oluşturulacaktır. Ayrıca her veritabanında bir max-session parametresi vardır, eğer toplam bağlantınız bu sınırı geçerse "Got minus one from a read call" alırsınız; Bilginize: Toplam oturumunuzu görmek için aşağıdaki sorguyu kullanın
SELECT username, count(username) FROM v$session
WHERE username IS NOT NULL group by username
Çözüm: DBA'mızın yardımıyla bu maksimum oturumu artırdık, böylece tüm uygulama minimum bağlantılarımızı barındırabilir hale getirdik.
Stephen C'nin cevabına ekleme yapmak istiyorum, benim durumum ilk noktadaydı. Şirkette IP adreslerini tahsis etmek için DHCP kullandığımızdan, DHCP tabii ki ne bana ne de Oracle'a sormadan makinemin adresini değiştirdi. Böylece birdenbire Oracle hiçbir şey yapmayı reddetti ve eksi bir korkunç istisna verdi. Eğer bu durumu sonsuza kadar aşmak istiyorsanız ve SQLNET.ora dosyasındaki TCP.INVITED_NODES burada belirtildiği gibi joker karakterleri kabul etmediğinden, IP adresi yerine makinenizin ana bilgisayar adını ekleyebilirsiniz.