2012-05-25 18 views
6

Ecco un pezzo di codice che abbiamo scritto tutto:Anomalia DD e pulizia delle risorse del database: esiste una soluzione pulita?

 
    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(); 
     } 
    } 

Se si omette il 'finalmente' a blocchi, poi si lascia le risorse del database penzoloni, che ovviamente è un potenziale problema. Tuttavia, se fai ciò che ho fatto qui - imposta il ResultSet su null al di fuori del blocco ** try **, e poi impostalo sul valore desiderato all'interno del blocco - PMD riporta un '' anomalia DD '. Nella documentazione, un'anomalia DD è descritto come segue:

DataflowAnomalyAnalysis: L'analisi del flusso di dati tiene traccia definizioni locali, non definizioni e riferimenti a variabili su percorsi diversi sui dati flow.From quelle informazioni non possono essere trovati vari problemi. [...] DD - Anomalia: viene ridefinita una variabile definita di recente. Questo è inquietante, ma non deve essere un bug.

Se si dichiara il ResultSet di fuori del blocco senza impostare un valore, è giustamente ottiene un errore di 'potrebbe non essere stato inizializzato la variabile' quando si esegue il if (record! = Null) test.

Ora, a mio parere, il mio uso qui non è un bug. Ma esiste un modo di riscrivere in modo pulito che non possa attivare l'avviso PMD? Non voglio in particolare disabilitare la regola DataFlowAnomalyAnalysis di PMD, in quanto l'identificazione delle anomalie UR e DU sarebbe effettivamente utile; ma queste anomalie DD mi fanno sospettare che potrei fare qualcosa di meglio - e, se non c'è modo migliore di farlo, ammontano a confusione (e dovrei forse vedere se posso riscrivere la regola PMD)

risposta

2

Penso questo è più chiaro:

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(); 
} 

Inoltre, nella versione della query non viene chiuso se records.close() genera un'eccezione.

1

penso che nota DD anomalia è più bug, di una caratteristica
Inoltre, il modo in cui risorse gratuite è un po 'incompleta, per esempio

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); 
     } 
    } 
} 

inoltre questo non è ancora a destra, perchè si dovrebbe risorse vicine come quella

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) { 
     } 
    } 
}