Viabilidade tratamento de exceções (MySQL)

Saudações.

Tenho uma dúvida sobre as exceções jogadas pelo banco de dados (MySQL).

Seria mais viável tratar assim:

public ResultSet runQuery(String query) throws SQLException{
  Statement stmt = getCon().createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
  ResultSet rs = stmt.executeQuery(query);
  return rs;
}

ou assim:

public ResultSet runQuery(String query){
  try{
    Statement stmt = getCon().createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
    ResultSet rs = stmt.executeQuery(query);
    return rs;
  }catch(Exception e){
    System.err.println(e.toString()); //Log
  }
}

No aguardo =]

Nenhum. Seu método runQuery não trata corretamente a exception em nenhum dos casos:

[code]public RowSet runQuery(String query){
try {
Statement stmt = null;
ResultSet rs = null;

  try{  
     stmt = getCon().createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);  
     rs = stmt.executeQuery(query);  

     CachedRowSet rowset = new CachedRowSetImpl();
     rowset.populate(rs);
     return rowset;  
  } finally {
     if (stmt != null) stmt.close();
     if (rs != null) rs.close();
  }

}catch(SQLException e){
throw new RuntimeException(e);
}
} [/code]

Você só deve reduzir a intensidade da exception para uma Runtime ou para um Log simples se a tratou. No caso, o tratamento da exception envolve o fechamento dos Statements e do ResultSet. O ideal seria fechar a conexão também, usando para isso um Pool de conexões.

O seu primeiro caso relança a exception, mas deixando os recursos abertos e tirando do programador que recebe a exception a possibilidade de trata-la. Por isso também é inadequado.

Esse tratamento, com o Pool, não é tão trivial. Uma sugestão é baixar uma biblioteca que já faça esse tipo de método exatamente como você quer corretamente. Essa biblioteca é o Spring.

Corrigi o código ali em cima para copiar os dados do ResultSet para um RowSet. Assim o ResultSet pode ser corretamente fechado.

Valeu.

Vou dar mais uma estudada aqui e ver o que consigo fazer ^^

Bom, já postei uma sugestão corrigida ali.
:slight_smile:

Outra coisa. Nunca faça catch em “Exception”. Como o código tratado só irá lançar uma SQLException, é bom dar o catch nela.

Aí se eventualmente uma RuntimeException inesperada de outro tipo for lançada, você não irá empacota-la na RuntimeException que trata de SQLExceptions, deixando o StackTrace final mais simples.

Sobre o catch em “Exception” você diz para ser mais específico?

Por ex: se eu sei que SÓ tenho SQLException, então eu trato como SQLException e não com a Exception genérica?

o que é o RuntimeException?

RuntimeException são exceções que não precisam ser capturadas com um try catch. Por isso o meu código ali converte a SQLException lançada numa RuntimeException. Note que não tem throws para aquela runtime que lanço.

Se você der um catch em Exception, você vai capturar tanto as SQLExceptions, como outras exceptions que os método lançarem, incluindo eventuais RuntimeExceptions. Por exemplo, vamos supor que o método executeQuery do ResultSet, por um erro de programação do driver, lance uma IndexOutOfBoundsException.

Isso não é uma SQLException, mas não precisou ser pega no try…catch por ser uma RuntimeException. O seu catch com Exception iria captura-la, um catch com SQLException não.

Legal. Esclareceu bastante coisa.

Obrigado