2009-10-13 11 views
8

Estoy usando JDBC para conectarme a un servidor de base de datos. La conexión es a través de una red inalámbrica y puede ser dudosa a veces. En el momento en que se pierde la conexión, necesito cerrar y reiniciar la aplicación.Conexión JDBC con reconexión automática

¿Alguien tiene algunos ejemplos de código donde podría escribir algún tipo de envoltorio para reconectar automáticamente y volver a ejecutar la última consulta? Esto ahorraría muchas molestias.

No estoy seguro de cómo debería/podría implementarse. Quizás ya haya algo disponible?

Respuesta

1

Deje que un grupo de conexiones lo maneje, muchos de ellos pueden validar una conexión. Lo mismo ocurre con DBPC que tiene un parámetro testOnBorrow que obliga a una comprobación de cordura en cada conexión antes de ser utilizada. El valor predeterminado de este parámetro es true, solo necesita validationQuery para establecerse en una cadena no nula para que tenga algún efecto. ¡Así que configure el validationQuery y listo! Consulte el documentation.

1

Consulte las bibliotecas de Universal Connection Pool (UCP) de Oracle. Son totalmente compatibles con JDBC 4.0 e implementan la llamada isValid() para verificar si una conexión está activa. Es fácil hacer esta comprobación, en caso de reconexión falsa, luego ejecutar su consulta.

Oracle UCP Download Page

Aunque sé que no preguntó por agrupaciones de conexiones, probablemente debería estar usando uno de todos modos por lo que este le ayudará a doble.

+0

El OP usa ** Firebird **, ¿por qué usaría el controlador de Oracle? Entonces, no implementaría la lógica de validación de conexión en mi código, prefiero usar un grupo que implemente esta verificación (y no es necesario usar un controlador JDBC 4.0 para esto). –

+0

Asumiendo que Firebird (de lo cual admito que sé cero) tiene un controlador JDBC, entonces todavía puede usar estas clases. Tenga en cuenta que se les llama UNIVERSAL Connection Pool: es la versión de Oracle de C3P0 o Proxool. Funcionan con cualquier controlador JDBC. Y sí, este conjunto hará la lógica de validación por sí mismo. – Gandalf

+0

Estoy de acuerdo con el conjunto de conexiones "universales". Sin embargo, "cumple con JBDC 4.0" se refiere a un controlador JDBC (Oracle específico esta vez), no un grupo. Ese era mi punto. –

4

Incluso si usa el conjunto de conexiones JDBC, ya sea el servidor de aplicaciones provisto o el pool común de Apache, vale la pena codificar una lógica de reintento. En función de la configuración de su servidor de aplicaciones, el servidor de la aplicación purgaría todas las conexiones agrupadas y recrearía un nuevo conjunto de conexiones. Aquí hay una muestra:

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

Si pierde la conexión mientras ejecuta una consulta, probablemente la perderá de nuevo durante el próximo intento. Solucione el problema real si esto sucede. –

Cuestiones relacionadas