当前位置: 首页 > 知识库问答 >
问题:

PreparedStatement和ResultSet上的资源泄漏

轩辕嘉平
2023-03-14

Eclipse显示警告消息,表示"资源泄漏,准备好的语句未在以下位置关闭"

在我看来,finally块负责关闭preparedstatement和rs对象。你知道为什么eclipse还在抱怨资源泄漏吗?

String ruleGrpId = null;
        int finalRuleID = 0;

        String saveRule1 = "INSERT INTO ..";
        String saveRule2 = "INSERT INTO ";

        String saveRule3 = "select ..._name = ?";

        PreparedStatement preparedstatement = null;
        ResultSet rs = null;

        try {
            if (objSomeRule.getRule() == 0) {

                preparedstatement = con.prepareStatement(saveRule1);
                preparedstatement.setString(1, ruleId);

                preparedstatement.executeUpdate();

                //Eclipse complains here
                preparedstatement = con.prepareStatement(saveRule2);

                preparedstatement.setInt(1, ruleID_2);
                preparedstatement.setString(2, ruleID_3);

                rs =  preparedstatement.executeQuery();

                if(rs.next()){
                    finalRuleID = rs.getInt(1);
                }else{
                    //complains here
                    preparedstatement = con.prepareStatement(saveRule3);
                    preparedstatement.setString(1, ruleID_4);
                    //complains here
                    rs =  preparedstatement.executeQuery();
                    if(rs.next()){
                        finalRuleID = rs.getInt("rulegroup_id");
                    }
                }
                objSomeRule.setRuleID(finalRuleID);

            }

        } finally {

            if(preparedstatement != null){
                preparedstatement.close();
            }

            if(rs != null){
                rs.close();
            }
        }

        return finalRuleID;
    }

共有3个答案

臧烨烁
2023-03-14

您创建了3个不同的PreparedStatement实例:

preparedstatement = con.prepareStatement(saveRule1);

preparedstatement = con.prepareStatement(saveRule2);

preparedstatement = con.prepareStatement(saveRule3);

您的变量preparedStatement只保存最后一个打开的变量,并且您没有对之前打开的其他变量的引用
因此,在您的finally部分中,您只关闭最后一个PreparedStatement

preparedstatement.close(); 

ResultSets也存在类似问题。您创建了两个实例,但只关闭了其中的一个。

东方淇
2023-03-14

因此,您的意思是在没有记录时创建另一个preparedStatement。

 if(rs.next())
 {
      finalRuleID = rs.getInt(1);
 }
 else
 {
    //close here first
    if(preparedstatement != null)
    {
       preparedstatement.close();
    }

    if(rs != null){
       rs.close();
    }

    preparedstatement = con.prepareStatement(saveRule3);
    // your code

但是,您还没有关闭上一个。我不太清楚,你为什么要这样做,但是,假设你需要这样做。然后,您应该先关闭上一个。

卢黎明
2023-03-14

重复使用变量preparedStatementrs可防止对变量的旧对象值调用close()。Try with resources是一个简洁的解决方案,因为close()是自动调用的,即使在抛出异常或在深度嵌套的Try中执行返回时也是如此。

    String ruleGrpId = null;
    int finalRuleID = 0;
    String saveRule1 = "INSERT INTO ..";
    String saveRule2 = "INSERT INTO ";
    String saveRule3 = "select ..._name = ?";

    if (objSomeRule.getRule() == 0) {
        try (PreparedStatement ps1 = con.prepareStatement(saveRule1)) {
            ps1.setString(1, ruleId);
            ps1.executeUpdate();
        }
        try (PreparedStatement ps2 = con.prepareStatement(saveRule2)) {
            ps2.setInt(1, ruleID_2);
            ps2.setString(2, ruleID_3);

            try (ResultSet rs2 =  ps2.executeQuery()) {

                if (rs2.next()) {
                    finalRuleID = rs2.getInt(1);
                } else {
                    try (Preparedstatement ps3 = con.prepareStatement(saveRule3)) {
                        ps3.setString(1, ruleID_4);
                        //complains here
                        try (ResultSet rs3 =  ps3.executeQuery()) {
                            if (rs3.next()) {
                                finalRuleID = rs3.getInt("rulegroup_id");
                            }
                        }
                    }
                }
            }
            objSomeRule.setRuleID(finalRuleID);
        }
    }

如果最后一个SELECT查询打算检索先前插入的自动增量ID,则可以使用getGeneratedKeys

 类似资料:
  • 问题内容: 假设您有以下代码: 重用ps变量是否有潜在的泄漏? 如果是这样,我不希望声明多个此类准备好的语句(ps1,ps2,ps3等)。我应该如何重构呢? 有人在想吗? 编辑 收到几个答案,说明这无关紧要。我想指出的是,我遇到的游标保持打开状态的时间过长,并且想知道该模式是否与此有关。 我的想法是: 第一条语句被取消引用并进行了GC处理,因此在此示例中,如何关闭第一个PreparedStatem

  • Eclipse Java警告:资源泄漏:“Unassigned Closeable Value”从不关闭 漏在哪里?

  • 大家晚上好。我是一个使用Java编程的完全初学者,我正在学习“扫描仪”,但是当我在Eclipse中键入这个基本代码时,我收到一条消息说“资源泄漏:‘扫描仪’永远不会关闭。 我做错了什么?

  • 我试图理解不对任何流调用close()会如何影响系统的性能和功能。为了做到这一点,我创建了下面的测试类。

  • 我正在使用Eclipse,并执行下面的函数,碰巧我打开了一个扫描器,然后,最后我关闭了它,但Eclipse一直说它没有关闭“资源泄漏:'Scanner'没有关闭”。我可以用try with resources来完成,警告消失了,但我想知道为什么我在这里尝试的方式不起作用

  • 多亏了约书亚我才想通的。