简体   繁体   English

在选中的Exception上无法清除java.sql.Statement

[英]Fail to cleanup java.sql.Statement on checked Exception

In my method show below find bug is specifying Fail to cleanup java.sql.Statement on checked Exception 在我的方法显示如下,查找错误是指定在检查Exception时无法清除java.sql.Statement

    public int updateSecurityCodeHistoryForMessage(String phone, String securityCodeHistoryId, String messageState, String messageId, String parentMessageId)
    {
            CaptivePortalLogger.appLog.error(MODULE+"Start : updateSecurityCodeHistoryForMessage::"+messageState);
            int result=-1;

        String query=null;
        Connection con = null;
        PreparedStatement pstmt =null;
        try
        {
            CaptivePortalLogger.sysOut.debug(MODULE + " (Method : isSecurityCodeUsed) Available Connection : "+ CaptivePortalDBConnection.getNumIdleConnections());
            CaptivePortalLogger.sysOut.debug(MODULE + " (Method : isSecurityCodeUsed) Active Connection : "+ CaptivePortalDBConnection.getNumActiveConnections() );

            con = CaptivePortalDBConnection.getDataSource().getConnection();
            CaptivePortalLogger.appLog.error(MODULE+" Before updateSecurityCodeHistoryForMessage into SendMessageAndReceiveReport: ");              

            query="UPDATE tblsecuritycodehistory SET messagestate = ?,messageid = ? WHERE securitycodehistoryid = ? AND mobileno = ?";

            CaptivePortalLogger.appLog.debug(MODULE + "for updateSecurityCodeHistoryForMessage in SendMessageAndReceiveReport Query : "+ query);

            pstmt = con.prepareStatement(query);
            pstmt.setString(1,messageState); //<b>line 556</b>
            pstmt.setString(2,messageId);
            pstmt.setString(3,securityCodeHistoryId);
            pstmt.setString(4,phone);
            result = pstmt.executeUpdate();

            CaptivePortalLogger.appLog.error(MODULE+" After updateSecurityCodeHistoryForMessage into SendMessageAndReceiveReport: result::"+result);
        }
        catch (Exception e) {
            result = -1;
            CaptivePortalLogger.traceLog.debug("Got an exception while updateSecurityCodeHistoryForMessage in SendMessageAndReceiveReport: ",e);
        }
        finally
        {
            CaptivePortalLogger.appLog.debug(MODULE+"Finally Start");
            try
            {
                if(pstmt!=null)
                    pstmt.close();
                if(con !=null)
                    con.close();

                CaptivePortalLogger.sysOut.debug(MODULE + " (Method : updateSecurityCodeHistoryForMessage) Closing connections done ....");

            }
            catch(Exception e)
            {
                CaptivePortalLogger.traceLog.debug("Error in closing sqlReader.",e);
            }
        }
    CaptivePortalLogger.appLog.error(MODULE+"End : updateSecurityCodeHistoryForMessage");
    return result;
}

无法清理java.sql.Statement

I find lots of links on stack but none of them able to solve my problem(may be im not able to understand them properly). 我在堆栈上找到很多链接,但没有一个能够解决我的问题(可能我无法正确理解它们)。 Any help will be appreciated. 任何帮助将不胜感激。

Thanks in Advance.......... 提前致谢..........

After updaing my finally block with a solution specfied by @Mark problem persists 使用@Mark问题指定的解决方案更新后,我的finally块仍然存在

finally
{
    CaptivePortalLogger.appLog.debug(MODULE+"Finally Start");
    try {
        if(pstmt!=null)
            pstmt.close();
    } catch (Exception ex) {
        // Log, ignore, etc
    }
    try {
        if(con !=null)
            con.close();
    } catch (Exception ex) {
        // Log, ignore, etc
    }
    CaptivePortalLogger.sysOut.debug(MODULE + " (Method : updateSecurityCodeHistoryForMessage) Closing connections done ....");
}

After using @Jon suggestion , my problem get resolved. 使用@Jon建议后,我的问题得到解决。 finally resolved code is :: 最后解决的代码是::

public int updateSecurityCodeHistoryForMessage(String phone, String securityCodeHistoryId, String messageState, String messageId, String parentMessageId)
    {
            CaptivePortalLogger.appLog.error(MODULE+"Start : updateSecurityCodeHistoryForMessage::"+messageState);
            int result=-1;
            String query=null;
            Connection con = null;
            PreparedStatement pstmt =null;
            try
            {
                CaptivePortalLogger.sysOut.debug(MODULE + " (Method : isSecurityCodeUsed) Available Connection : "+ CaptivePortalDBConnection.getNumIdleConnections());
                CaptivePortalLogger.sysOut.debug(MODULE + " (Method : isSecurityCodeUsed) Active Connection : "+ CaptivePortalDBConnection.getNumActiveConnections() );

                con = CaptivePortalDBConnection.getDataSource().getConnection();
                CaptivePortalLogger.appLog.error(MODULE+" Before updateSecurityCodeHistoryForMessage into SendMessageAndReceiveReport: ");              

                query="UPDATE tblsecuritycodehistory SET messagestate = ?,messageid = ? WHERE securitycodehistoryid = ? AND mobileno = ?";

                CaptivePortalLogger.appLog.debug(MODULE + "for updateSecurityCodeHistoryForMessage in SendMessageAndReceiveReport Query : "+ query);
                try
                {
                    pstmt = con.prepareStatement(query);
                    pstmt.setString(1,messageState);
                    pstmt.setString(2,messageId);
                    pstmt.setString(3,securityCodeHistoryId);
                    pstmt.setString(4,phone);
                    result = pstmt.executeUpdate();
                }
                catch(SQLException e1)
                {
                    CaptivePortalLogger.traceLog.debug("Error in closing sqlReader.",e1);
                }
                finally{
                    if(pstmt!=null)
                    pstmt.close();
                }

                CaptivePortalLogger.appLog.error(MODULE+" After updateSecurityCodeHistoryForMessage into SendMessageAndReceiveReport: result::"+result);
            }
            catch (SQLException e2) {
                result = -1;
                CaptivePortalLogger.traceLog.debug("Got an exception while updateSecurityCodeHistoryForMessage in SendMessageAndReceiveReport: ",e2);
            }
            finally
            {
                CaptivePortalLogger.appLog.debug(MODULE+"Finally Start");
                try
                {
                    if(con !=null)
                        con.close();

                    CaptivePortalLogger.sysOut.debug(MODULE + " (Method : updateSecurityCodeHistoryForMessage) Closing connections done ....");

                }
                catch(SQLException e)
                {
                    CaptivePortalLogger.traceLog.debug("Error in closing sqlReader.",e);
                }
            }
        CaptivePortalLogger.appLog.error(MODULE+"End : updateSecurityCodeHistoryForMessage");
        return result;
    }

Look at this code: 看看这段代码:

if(pstmt!=null)
    pstmt.close();
if(con !=null)
    con.close();

Now consider that pstmt.close() can throw an exception... which means con.close() wouldn't be called. 现在考虑pstmt.close()可以抛出异常......这意味着不会调用con.close()

If you're using Java 7, use a try-with-resources statement instead, but otherwise you should have a separate try/finally block for each resource. 如果您使用的是Java 7,请改用try-with-resources语句,否则您应该为每个资源设置一个单独的try / finally块。

try {
   connection = ...;
   try {
      statement = ...;
   } finally {
      // Clean up statement
   }
} finally {
   // Clean up connection
}

I'd also strongly recommend against catching blanket Exception - it's better to catch specific exceptions which you can actually handle, and let other exceptions propagate up the stack. 我还强烈建议不要捕捉毯子Exception - 最好抓住你可以实际处理的特定异常,并让其他异常在堆栈中传播。 Also, you appear to be using integer values to signal success or failure of your method - that's not idiomatic Java; 此外,您似乎使用整数值来表示您的方法的成功或失败 - 这不是惯用的Java; exceptions are preferred for error handling, in general. 通常,异常是错误处理的首选。

The problem is that if pstmt.close() throws an Exception, then the connection is never closed. 问题是如果pstmt.close()抛出异常,那么连接永远不会关闭。

Either do not close the statement in the finally (as drivers are required to close Statement objects if the Connection is closed), or put both in their own try..catch -block. 要么不关闭finally中的语句(因为如果Connection已关闭,则需要关闭Statement对象的驱动程序),或者将它们都放在自己的try..catch -block中。 Eg: 例如:

finally
{
    CaptivePortalLogger.appLog.debug(MODULE+"Finally Start");
    try {
        if(pstmt!=null)
            pstmt.close();
    } catch (Exception ex) {
        // Log, ignore, etc
    }
    try {
        if(con !=null)
            con.close();
    } catch (Exception ex) {
        // Log, ignore, etc
    }
    CaptivePortalLogger.sysOut.debug(MODULE + " (Method : updateSecurityCodeHistoryForMessage) Closing connections done ....");
}

Firebug is correct. 萤火虫是正确的。

You should close all your SQL resources in a finally block, using individually wrapped calls to close methods. 您应该使用单独包装的close方法调用来关闭finally块中的所有SQL资源。

You can do it with a utility class: 您可以使用实用程序类来执行此操作:

package persistence;

public class DatabaseUtils {
    // similar methods for ResultSet and Connection
    public static void close(Statement s) {
        try {
            if (s != null) {
                s.close();
            }
        } catch (SQLException e) {
            // Log the exception
        }       
    }
} 

Call the close method in a finally block in the method that created the resource. 在创建资源的方法中的finally块中调用close方法。

尝试在单独的try / catch / finally块中清理/关闭资源,否则如果任何一个抛出异常,则其余的将保持未闭合。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用java.sql.Statement执行多行sybase语句 - Execute Multiline sybase statement with java.sql.Statement 为什么java.sql.Statement是接口而不是抽象类? - Why is java.sql.Statement an interface and not an abstract class? 在单个java.sql.Statement上执行多个DML - Execute Multiple DML on single java.sql.Statement 寻找一种方法来防止在项目中使用java.sql.Statement - Looking for a way to prevent to usage of java.sql.Statement in project 为什么java.sql.Statement破坏了向后兼容性? - Why does java.sql.Statement break backward compatibility? java.sql.Statement或java.sql.PreparedStatement - 带参数的可滚动结果集 - java.sql.Statement or java.sql.PreparedStatement - scrollable resultset with parameters java.sql.Connection.close()对java.sql.Statement对象等的影响 - Impact of java.sql.Connection.close() on java.sql.Statement objects and the like Android Studio jTDS java.lang.NullPointerException java.sql.Statement java.sql.Connection.createStatement() 对空对象引用 - Android Studio jTDS java.lang.NullPointerException java.sql.Statement java.sql.Connection.createStatement() on a null object reference 在Java中创建自定义SQL检查的异常? - Creating a custom SQL checked exception in java? SQL异常列无效,java sql语句 - SQL exception column invalid, java sql statement
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM