2011-10-14 21 views
26

ja (z powodzeniem) łączący się z bazą danych przy użyciu następujących:Java JDBC stan połączenia

java.sql.Connection connect = DriverManager.getConnection(
    "jdbc:mysql://localhost/some_database?user=some_user&password=some_password"); 

Co powinienem być sprawdzenie, czy połączenie jest wciąż otwarta i się po jakimś czasie?
Miałem nadzieję, że coś takiego jak connect.isConnected(); będzie dostępne dla mnie.

Odpowiedz

15

Nic. Po prostu wykonaj zapytanie. Jeśli połączenie zginie, albo sterownik JDBC połączy się ponownie (jeśli go obsługuje i włączasz go w łańcuchu połączenia - większość go nie obsługuje), albo otrzymasz wyjątek.

Jeśli zaznaczysz połączenie jest w górę, to może się przewrócić, zanim faktycznie wykonać zapytanie, więc zyskujesz nic sprawdzając.

Powiedział, że wiele pula połączeń sprawdzić poprawność połączenia, wykonując coś takiego SELECT 1 przed przekazaniem połączenia się. Ale to nic innego, jak tylko wykonanie zapytania, więc równie dobrze można wykonać zapytanie biznesowe.

+1

Istnieje pewna korzyść z testowania połączenia przed jego użyciem (szczególnie jeśli jest to połączenie długowieczne i sieć bazowa mogła go użyć). Ale jest to również dokładne, ponieważ nadal musisz radzić sobie z błędami we własnym kodzie, ponieważ może on spaść w każdej chwili. – rogerdpack

12

Użyj funkcji Connection.isClosed().

W JavaDoc stany:

Pobiera czy Connection obiekt został zamknięty. Połączenie jest zamykane, jeśli zamknęło się zamknięcie metody lub jeśli wystąpiły pewne błędy krytyczne w postaci . Ta metoda jest gwarantowana return true tylko wtedy, gdy zostanie wywołana po wywołaniu metody Connection.close .

+3

Jako javadoc mówi, że to nie będzie ** ** dać poprawną odpowiedź w tej sprawie. Opisze tylko czy wywołano 'close()'. –

+1

OK po kilku eksperymentach ze sterownikiem JDBC Postgres (przynajmniej), zasadniczo, jeśli podstawowe połączenie "zostanie utracone", 'isClosed()' nadal zwróci true. Jednakże, gdy * użyjesz * połączenia i podniesie każdy wyjątek, po tym punkcie 'isClosed()' zwróci teraz wartość true. Więc w zasadzie możesz "uciec" używając 'isClosed' (i uniknąć opóźnienia dodatkowego wywołania' isValid() '), jeśli możesz sobie pozwolić na przerwane zapytanie tutaj lub tam. Inna niż 'isValid()' jest dobrym sposobem na sprawdzenie, ale wymaga dodatkowego czasu podróży w obie strony. – rogerdpack

+0

Dzięki człowieku .. To działało jak czar. –

33

Twoja najlepsza szansa jest po prostu wykonać prostą kwerendę przeciwko jednej tabeli, np:

select 1 from SOME_TABLE; 

Och, właśnie widziałem jest nowa metoda dostępny od 1,6:

java.sql.Connection.isValid(int timeoutSeconds):

Zwraca tRUE jeśli połączenie nie zostało zamknięte i jest nadal ważny. Sterownik powinien przesłać zapytanie dotyczące połączenia lub użyć innego mechanizmu , który pozytywnie sprawdza, czy połączenie jest nadal ważne, gdy ta metoda jest wywoływana. Zapytanie przesłane przez sterownik w celu sprawdzenia poprawności połączenia zostanie wykonane w kontekście bieżącej transakcji .

+0

Postgresql jdbc wykonuje "wybierz 1", dla rekordu. – rogerdpack

3

Jeśli używasz MySQL

public static boolean isDbConnected() { 
    final String CHECK_SQL_QUERY = "SELECT 1"; 
    boolean isConnected = false; 
    try { 
     final PreparedStatement statement = db.prepareStatement(CHECK_SQL_QUERY); 
     isConnected = true; 
    } catch (SQLException | NullPointerException e) { 
     // handle SQL error here! 
    } 
    return isConnected; 
} 

nie testowałem z innymi bazami danych. Mam nadzieję, że to jest pomocne.

+0

Skąd pochodzi 'db'? – MonoThreaded

+0

Zobacz w pytaniu "połącz" zmienna to 'db' bez względu na to, jak go nazwiesz. –

+0

Następnie możesz zamknąć swoje PreparedStatement, aby zapobiec wyciekom pamięci. – MonoThreaded

4

Można również użyć

public boolean isDbConnected(con Connection) { 
    //final String CHECK_SQL_QUERY = "SELECT 1"; 
    try { 
     if(!con.isClosed() || con!=null){ 
      return true; 
     } 
    } catch (SQLException e) { 
     return false; 
    } 
    return false; 
} 
+2

Powinno być, jeśli (con! = Null ||! Con.isClosed()), tak aby twoje sprawdzenie najpierw znajduje się na obiekcie, jeśli jest puste, nie będzie kontynuowane sprawdzaniem poprawności instrukcji JEŻELI. Twoje będą powodować wyjątki, ponieważ con może mieć wartość NULL. Wtedy nie potrzebujesz całej próby złapania. – Switch

Powiązane problemy