Соединение Oracle jdbc занимает много времени, затем java.sql.SQLRecoverableException: IO Error: Broken pipe

В моем приложении я использую подключение к Oracle. Иногда показывает ошибку Broken pipe, но не всегда.

  1. Почему подключение занимает более 1 минуты (вызывает ошибку «Сломанная труба»)? БД и приложение на одном хосте.
  2. Зачем переподключать 5-секундный цикл? Я предполагаю, что "Con time=30066" означает, что это было сделано 7 раз.

Пожалуйста, помогите и спасибо.

2016-08-05 10:00:40 (Con time=1041,  Qry time=12)
2016-08-05 10:00:43 (Con time=89,  Qry time=1)
2016-08-05 10:00:46 (Con time=65,  Qry time=7)
2016-08-05 10:00:49 (Con time=59,  Qry time=1)
2016-08-05 10:00:52 (Con time=58,  Qry time=1)
2016-08-05 10:00:55 (Con time=62,  Qry time=2)
2016-08-05 10:00:58 (Con time=100,  Qry time=1)
2016-08-05 10:01:01 (Con time=66,  Qry time=1)
2016-08-05 10:01:04 (Con time=60,  Qry time=1)
2016-08-05 10:01:08 (Con time=63,  Qry time=1)
2016-08-05 10:01:11 (Con time=68,  Qry time=0)
2016-08-05 10:01:14 (Con time=61,  Qry time=1)
...
2016-08-05 15:09:01 (Con time=30066,  Qry time=9)
2016-08-05 15:10:01 (Con time=65,  Qry time=11)
2016-08-05 15:11:06 (Con time=5059,  Qry time=11)
2016-08-05 15:12:07 (Con time=91,  Qry time=11)
2016-08-05 15:13:07 (Con time=73,  Qry time=12)
2016-08-05 15:14:07 (Con time=56,  Qry time=275)
2016-08-05 15:15:27 (Con time=20093,  Qry time=13)

java.sql.SQLRecoverableException: IO Error: Broken pipe
        at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:498)
        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:322)
        at java.sql.DriverManager.getConnection(DriverManager.java:297)
        at DbCon.getDate(DbCon.java:325)
        at DbCon.main(DbCon.java:104)
Caused by: java.net.SocketException: Broken pipe
        at java.net.SocketOutputStream.socketWrite0(Native Method)
        at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:103)
        at java.net.SocketOutputStream.write(SocketOutputStream.java:147)
        at oracle.net.ns.DataPacket.send(DataPacket.java:210)
        at oracle.net.ns.NetOutputStream.flush(NetOutputStream.java:230)
        at oracle.net.ns.NetInputStream.getNextPacket(NetInputStream.java:321)
        at oracle.net.ns.NetInputStream.read(NetInputStream.java:268)
        at oracle.net.ns.NetInputStream.read(NetInputStream.java:190)
        at oracle.net.ns.NetInputStream.read(NetInputStream.java:107)
        at oracle.jdbc.driver.T4CSocketInputStreamWrapper.readNextPacket(T4CSocketInputStreamWrapper.java:124)
        at oracle.jdbc.driver.T4CSocketInputStreamWrapper.read(T4CSocketInputStreamWrapper.java:80)
        at oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.java:1137)
        at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:350)
        at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:227)
        at oracle.jdbc.driver.T4CTTIoauthenticate.doOSESSKEY(T4CTTIoauthenticate.java:407)
        at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:416)
        ... 8 more



import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

import oracle.jdbc.OracleConnection;

public class DbCon {


    /**JDBC Driver*/
    public static String JDBC_DRIVER = "oracle.jdbc.driver.OracleDriver";
    /**URL*/
    public static String JDBC_URL="jdbc:oracle:thin:XXXXXXXXXXXXXXX";

    public static void main(String[] args) {
        while(true){
            System.out.println(getDate());
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }


    /**
     * Get date for test
     * @return
     */
    public static String getDate() {
            Connection con = null;// SqlConnection
            ResultSet rs = null;// IDataReader
            PreparedStatement ps = null;
            String str = "";
            long timeCon = System.currentTimeMillis();
            try {

                    Class.forName(JDBC_DRIVER);
                    con = DriverManager.getConnection(JDBC_URL);
                    str = " (Con time="+(System.currentTimeMillis()-timeCon)+", ";
                    StringBuffer sbSql = new StringBuffer()
                                    .append("SELECT SYSDATE FROM DUAL");
                    ps = con.prepareStatement(sbSql.toString());
                    long timeQry = System.currentTimeMillis();
                    rs = ps.executeQuery();
                    while (rs.next()) {str = rs.getString(1) + str;}
                    str = str +" Qry time="+(System.currentTimeMillis()-timeQry)+")";
                    return str;
            } catch (SQLException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}
            finally {
                    if (rs != null) {try {rs.close();} catch (Exception ex) {ex.printStackTrace();}}
                    if (ps != null) {try {ps.close();} catch (Exception ex) {ex.printStackTrace();}}
                    if (con != null) {try {con.close();} catch (Exception ex) {ex.printStackTrace();}}
                    str =  " (Con time="+(System.currentTimeMillis()-timeCon)+")";
            }
            return str;
    }


}

person Enoo Lee    schedule 05.08.2016    source источник
comment
По этому поводу уже есть вопрос ---› stackoverflow.com/questions/9766168/.   -  person ivanzg    schedule 05.08.2016
comment
Спасибо. Я решил проблему.   -  person Enoo Lee    schedule 12.08.2016


Ответы (1)


Причина:

Проблема может заключаться в проблемах поиска между IPv6 и IPv4. Если сервер системы доменных имен (DNS) не настроен для обработки запросов IPv6, приложению может потребоваться дождаться истечения времени ожидания запроса IPv6 для запросов IPv6.

Эти потоки ожидают ответа на запрос IPv6. Вероятно, DNS-сервер не отвечает на запрос IPv6.

в java.net.Inet6AddressImpl.getLocalHostName(собственный метод) в java.net.InetAddress.getLocalHost(InetAddress.java:123)

Решение:

Моя система использует только IPv4, поэтому я установил следующий аргумент для пакетной команды.

java -Djava.net.preferIPv4Stack=true ...

И теперь все в порядке.

ссылка: http://www-01.ibm.com/support/docview.wss?uid=swg21170467

person Enoo Lee    schedule 12.08.2016