【问题标题】:finding DB connections that are not closed properly查找未正确关闭的数据库连接
【发布时间】:2013-04-09 19:35:49
【问题描述】:

在一个大型项目的代码中发现了一些泄漏,其中数据库连接已打开但未关闭。 DB 是 DB2,连接是在 java 程序中打开的,并且在 try catch 中没有正确关闭,finally..

有没有办法在java中搜索所有打开连接但不关闭它的方法? 我试图避免手动查看打开连接的每个方法以查看它是否正确关闭。

对这项乏味任务的任何帮助都会很酷。

【问题讨论】:

    标签: java sql database connection


    【解决方案1】:

    FindBugsPMD(开源静态代码检查器)都支持检测未关闭的数据库连接。它们可以集成到您的构建过程和/或 IDE 中。

    尤其是 PMD,默认情况下可能会产生噪音,但可以使用 custom ruleset 或通过 other means 将其调低。

    【讨论】:

      【解决方案2】:

      我首先想到的是实现一个利用抽象语法树的工具(例如,作为一个 Eclipse 插件)。您可以编写一个工具来检查您的方法,检查节点的连接初始化命令,并检查关闭命令。 看: - http://en.wikipedia.org/wiki/Abstract_syntax_tree 见: - http://www.eclipse.org/articles/Article-JavaCodeManipulation_AST/index.html

      否则,我认为也可以使用某种自定义解析器来检查与等效的数据库打开语句在同一级别内是否存在等效的 .close() 语句。 你必须检查你有多少级别(使用“{”和“}”字符。

      见:Write a custom syntax interpreter in java?

      【讨论】:

        【解决方案3】:

        关于您的问题,您还可以使用确保关闭连接的方法来实现一个类。下面我贴了一个例子。

        public class Cleaner {
        
        private String dbName = "";
        private Connection connection;
        
        public static void CloseResSet(ResultSet res) {
            try {
                if (res != null) {
                    res.close();
                }
            } catch (SQLException e) {
                writeMessage(e, "CloseResSet()");
            }
        }
        
        public static void closeStatement(Statement stm) {
            try {
                if (stm != null) {
                    stm.close();
                }
            } catch (SQLException e) {
                writeMessage(e, "closeStatement()");
            }
        }
        
        public static void closeConnection(Connection connection) {
            try {
                if (connection != null) {
                    connection.close();
                }
            } catch (SQLException e) {
                writeMessage(e, "closeConnection()");
            }
        }
        
        public static void rollBack(Connection connection) {
            try {
                if (connection != null && !connection.getAutoCommit()) {
                    connection.rollback();
                }
            } catch (SQLException e) {
                writeMessage(e, "rollBack()");
            }
        }
        
        public static void setAutoCommit(Connection connection) {
            try {
                if (connection != null && !connection.getAutoCommit()) {
                    connection.setAutoCommit(true);
                }
            } catch (SQLException e) {
                writeMessage(e, "setAutoCommit()");
            }
        }
        
        public static void writeMessage(Exception e, String message) {
            System.err.println("*** Error: " + message + ". ***");
            e.printStackTrace(System.err);
        }
        
        private void OpenConnection() {
            try {
                connection = DriverManager.getConnection(dbName);
                System.out.println("Databaseconnection established");
            } catch (SQLException e) {
                Cleaner.writeMessage(e, "Constructor");
                Cleaner.closeConnection(connection);
            }
        }
        
        private void closeConnection() {
            System.out.println("Closes databaseconnection");
            Cleaner.closeConnection(connection);
        }
        public static void main(String[] args){
            }
        }
        

        【讨论】:

        • 谢谢!我们有这样一个类,但是如果没有人调用这些方法就没有用了:s
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-29
        • 1970-01-01
        • 2012-03-29
        • 2012-04-10
        相关资源
        最近更新 更多