Соединение JDBC с автоматическим переподключением - PullRequest
11 голосов
/ 14 октября 2009

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

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

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

Ответы [ 3 ]

6 голосов
/ 14 октября 2009

Даже если вы используете пул соединений JDBC, либо предоставленный сервер приложений, либо пул общих соединений Apache, стоит кодировать логику повторов.В зависимости от конфигурации вашего сервера приложений, сервер приложений будет очищать все пулы соединений и воссоздавать новый набор соединений.Вот образец:

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));
3 голосов
/ 14 октября 2009

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

1 голос
/ 14 октября 2009

Проверьте библиотеки универсального пула соединений (UCP) Oracle. Они полностью соответствуют JDBC 4.0 и реализуют вызов isValid(), чтобы проверить, является ли соединение активным. Это легко сделать, если false переподключить, а затем выполнить запрос.

Страница загрузки Oracle UCP

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

...