2012-05-25 21 views
6

Oto fragment kodu mamy napisane:DD anomalia i czyszczenie zasobów bazy danych: czy istnieje czyste rozwiązanie?

 
    public CustomerTO getCustomerByCustDel(final String cust, final int del) 
      throws SQLException { 
     final PreparedStatement query = getFetchByCustDel(); 
     ResultSet records = null; 
     try { 
      query.setString(1, cust); 
      query.setInt(2, del); 
      records = query.executeQuery(); 

      return this.getCustomer(records); 
     } finally { 
      if (records != null) { 
       records.close(); 
      } 
      query.close(); 
     } 
    } 

Jeśli pominąć „wreszcie” blok, a następnie pozostawić zwisające zasobów bazy danych, co oczywiście jest potencjalnym problemem. Jeśli jednak zrobisz to, co tutaj zrobiłem - ustaw ResultSet na wartość null poza blokiem ** try **, a następnie ustaw go na pożądaną wartość wewnątrz bloku - PMD zgłasza "anomalię DD". W dokumentacji nieprawidłowość DD jest opisana następująco:

Analizy danych przepływu danych: Analiza przepływu danych śledzi lokalne definicje, niedefiniowania i odniesienia do zmiennych na różnych ścieżkach przepływu danych. Z tych informacji można znaleźć różne problemy. [...] DD - Anomalia: nowo zdefiniowana zmienna zostaje przedefiniowana. To jest złowieszcze, ale nie musi być błędem.

Jeśli zadeklarujesz wynikowego zewnątrz bloku bez ustawiania wartości, to słusznie dostać „zmienna nie mogły zostać zainicjowany” błąd podczas zrobić if (zapisy! = Null) testową.

Teraz, moim zdaniem, moje użycie tutaj nie jest błędem. Ale czy istnieje sposób na poprawne przepisanie, które nie spowodowałoby ostrzeżenia PMD? Nie chcę szczególnie wyłączać zasady DataFlowAnomalyAnalysis PMD, ponieważ identyfikacja anomalii UR i DU byłaby rzeczywiście przydatna; ale te anomalie DD sprawiają, że podejrzewam, że mogłem robić coś lepszego - i, jeśli nie ma lepszego sposobu na zrobienie tego, są one bałaganem (i powinienem spojrzeć na to, czy mogę przepisać zasadę PMD)

Odpowiedz

2

Myślę, że ten jest wyraźniejszy:

PreparedStatement query = getFetchByCustDel(); 
try { 
    query.setString(1, cust); 
    query.setInt(2, del); 
    ResultSet records = query.executeQuery(); 
    try { 
     return this.getCustomer(records); 
    } finally { 
     records.close(); 
    } 
} finally { 
    query.close(); 
} 

również w wersji zapytanie nie zostanie zamknięte, jeśli records.close() zgłasza wyjątek.

1

myślę, że DD anomalia uwaga jest więcej błędów, niż cecha
Również sposób wolnych zasobów jest nieco niekompletne, np

PreparedStatement pstmt = null; 
Statement st = null; 

try { 
    ... 
} catch (final Exception e) { 
    ... 
} finally { 
    try{ 
     if (pstmt != null) { 
      pstmt.close(); 
     } 
    } catch (final Exception e) { 
     e.printStackTrace(System.err); 
    } finally { 
     try { 
      if (st != null) { 
       st.close(); 
      } 
     } catch (final Exception e) { 
      e.printStackTrace(System.err); 
     } 
    } 
} 

ponadto nie jest to jeszcze raz w prawo, bo zalecana blisko takie zasoby:

PreparedStatement pstmt = null; 
Throwable th = null; 

try { 
    ... 
} catch (final Throwable e) { 
    <something here> 
    th = e; 
    throw e; 
} finally { 
    if (th == null) { 
     pstmt.close(); 
    } else { 
     try { 
      if (pstmt != null) { 
       pstmt.close(); 
      } 
     } catch (Throwable u) { 
     } 
    } 
}