2009-10-13 4 views
8

Я использую JDBC для подключения к серверу базы данных. Соединение по беспроводной сети и может быть изворотливым в разы. В момент потери соединения мне нужно закрыть и перезапустить приложение.Соединение JDBC с автоматическим повторным подключением

Есть ли у кого-нибудь примеры кода, где я мог бы написать какую-то оболочку для автоматического повторного подключения и повторного запуска последнего запроса? Это сэкономит массу неприятностей.

Я просто не уверен, как это должно/могло быть реализовано. Возможно, что-то уже есть?

ответ

1

Позвольте пулу соединений обработать это для вас, многие из них могут проверить соединение. Точно так же DBPC, который имеет параметр testOnBorrow, который заставляет проверку работоспособности каждого соединения до его использования. Значением по умолчанию этого параметра является true, для которого требуется только validationQuery, чтобы иметь значение, отличное от нуля. Так что установите validationQuery, и там вы идете! Проверьте documentation.

1

Ознакомьтесь с библиотеками универсальных пулов Oracle (UCP). Они полностью совместимы с JDBC 4.0 и реализуют вызов isValid(), чтобы проверить, жив ли соединение. Легко выполнить эту проверку, если ложное повторное подключение, а затем запустить запрос.

Oracle UCP Download Page

В то время как я знаю, что вы не спрашивали о пулов соединений, вероятно, вы должны использовать один в любом случае, так что это поможет вам в два раза.

+0

ОП использует ** Firebird **, зачем ему использовать драйвер Oracle? Тогда я бы не реализовал логику проверки соединения в своем коде, я бы предпочел использовать пул, который реализует эту проверку (и для этого нет необходимости использовать драйвер JDBC 4.0). –

+0

Предполагая, что Firebird (к которому я допускаю, что я знаю нуль) имеет драйвер JDBC, тогда он все еще может использовать эти классы. Обратите внимание, что они называются UNIVERSAL Connection Pool - это версия Oracle C3P0 или Proxool. Они работают с любым драйвером JDBC. И да, этот пул сделает логику проверки на своем собственном. – Gandalf

+0

Я согласен с «Универсальным» пулом соединений. Однако «JBDC 4.0-совместимый» относится к JDBC-драйверу (на данный момент определенному Oracle), а не к пулу. Это была моя точка зрения. –

4

Даже если вы используете пул соединений JDBC с предоставленным сервером приложений или с пулом apache commons, целесообразно закодировать логику повтора. На основе конфигурации вашего сервера приложений сервер приложений очистит все объединенные соединения и воссоздает новый набор подключений. Вот пример:

Connection conn = null; 
    Statement stmt = null; 
    ResultSet rs = null; 
    // 
    // How many times do you want to retry the transaction 
    // (or at least _getting_ a connection)? 
    // 
    int retryCount = 5; 
    boolean transactionCompleted = false; 
    do { 

    try { 
    conn = getConnection(); // assume getting this from a 
          // javax.sql.DataSource, or the 
          // java.sql.DriverManager 

    retryCount = 0; 
    stmt = conn.createStatement(); 
    String query = "Some sample SQL"; 
    rs = stmt.executeQuery(query); 
    while (rs.next()) { 
    } 
    rs.close(); 
    rs = null; 
    stmt.close(); 
    stmt = null; 

    conn.close(); 
    conn = null; 
    transactionCompleted = true; 
    } catch (SQLException sqlEx) { 
    // 
    // The two SQL states that are 'retry-able' 
    // for a communications error. 
    // 
    // Only retry if the error was due to a stale connection, 
    // communications problem 
    // 
    String sqlState = sqlEx.getSQLState(); 
    if ("Substitute with Your DB documented sqlstate number for stale connection".equals(sqlState)) { 
     retryCount--; 
    } else { 
     retryCount = 0; 
    } 
    } finally { 
    if (rs != null) { 
     try { 
      rs.close(); 
     } catch (SQLException sqlEx) { 
      // log this 
     } 
    } 
    if (stmt != null) { 
     try { 
      stmt.close(); 
     } catch (SQLException sqlEx) { 
      // log this 
     } 
    } 
    if (conn != null) { 
     try { 
      // 
      // If we got here, and conn is not null, the 
      // transaction should be rolled back, as not 
      // all work has been done 
      try { 
       conn.rollback(); 
      } finally { 

          conn.close(); 
        } 
       } catch (SQLException sqlEx) { 
        // 
        // If we got an exception here, something 
        // pretty serious is going on, so we better 
        // pass it up the stack, rather than just 
        // logging it. . . 
        throw sqlEx; 
       } 
      } 
     } 
    } while (!transactionCompleted && (retryCount > 0)); 
} 
+0

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