2016-11-10 2 views
0

Я подозреваю, что это может быть ложным положительным, но я не могу быть уверен, поэтому я немного смущен. Я использую Eclipse Neon, и проблема появляется в третий раз, когда я готовлю заявление. Я делаю что-то почти идентичное ниже, без ошибок.Утечка ресурса PreparedStatement при подготовке заявления

try{ 
     Connection con = MySQL.connection; 
     PreparedStatement ps = con.prepareStatement("SELECT * from UsernameData " 
       + "WHERE UUID = '" + player.getUniqueId() + "'"); 
     ResultSet rs = ps.executeQuery(); 
     if(rs.next() == true){ 
      ps = con.prepareStatement("update UsernameData set UUID = ?, Username = ? where UUID = ?"); 
      ps.setString(1, uuid); 
      ps.setString(2, username); 
      ps.setString(3, uuid); 
      ps.execute(); 
      ps.close(); 
      rs.close(); 
      return; 
     } 
     ps = con.prepareStatement("insert into UsernameData(UUID, Username)" 
       + " values (?, ?)"); 
     ps.setString(1, uuid); 
     ps.setString(2, username); 
     ps.execute(); 
     ps.close(); 
     rs.close(); 
     return; 
    }catch(SQLException e){ 
     Bukkit.getServer().getLogger().warning("SQL Error: " + e); 
    } 

ответ

0

Вы не закрывать первый набор ресурсов, когда вы топать на ps для вашей вставки.

Вы должны также рассмотреть возможность использования примерочных с-ресурсами:

try (Connection con = MySQL.connection; 
      PreparedStatement ps = con.prepareStatement("SELECT * from UsernameData " 
        + "WHERE UUID = '" + player.getUniqueId() + "'"); 
      PreparedStatement ps2 = con.prepareStatement("update UsernameData set UUID = ?, Username = ? where UUID = ?"); 
      PreparedStatement ps3 = con.prepareStatement("insert into UsernameData(UUID, Username)" 
        + " values (?, ?)"); 
      ResultSet rs = ps.executeQuery()) { 
     if (rs.next() == true) { 
      ps2.setString(1, uuid); 
      ps2.setString(2, username); 
      ps2.setString(3, uuid); 
      ps2.execute(); 
      return; 
     } 
     ps3.setString(1, uuid); 
     ps3.setString(2, username); 
     ps3.execute(); 
     return; 
    } catch (SQLException e) { 
     Bukkit.getServer().getLogger().warning("SQL Error: " + e); 
    } 

Да, второй и третий PreparedStatement потенциально впустую. Если хотите, вы можете обернуть их собственными средствами try-with-resources.

Но суть проблемы - это топать по переменной ps.

+0

Ммм, что имеет смысл, спасибо. – Haydenman2

+0

не обязательно. Я не думаю, что это похоже на любую передовую практику или проблему с повторным использованием одного и того же оператора или переменной PreparedStatement. Я разместил это http://stackoverflow.com/questions/850878/does-setting-java-objects-to-null-do-anything-anymore – Acewin

+0

, просто закрывая инструкцию, используя ps.close(); Это хорошо. Потенциальная утечка не потому, что вы выполняете ps.execute(); или ps.close(); это будет, когда вы не сможете их закрыть. И это гораздо важнее связь, так как до тех пор, пока вы не позвонили в базу данных connection.close, предполагается, что ваше соединение открыто, даже если вы отменили ссылку на него, установив для переменной подключения значение null. – Acewin