JDBC连接太多了

时间:2014-06-02 00:35:10

标签: java mysql sql database jdbc

以下是连接方法:

private static Connection connection = null;

/**
 * Gets the database connection.
 */
public static Connection getConnection() {
    return Storage.connection;
}

/**
 * Connects to the database.
 */
public static void connectToDatabase() {
    try {
        String userName = "root";
        String password = "mysql";
        String url = "jdbc:mysql://localhost/secondsemesterprojectdanishcrowncaos";
        Class.forName("com.mysql.jdbc.Driver").newInstance();
        Storage.connection = DriverManager.getConnection(url, userName,
                password);
        Storage.connection
                .setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
        Storage.connection.setAutoCommit(false);
    } catch (Exception e) {
        System.err.println("Cannot connect to database server." + e);
    }
}

/**
 * Terminates the database connection.
 */
public static void disconnectDatabase() {
    if (Storage.connection != null) {
        try {
            Storage.connection.close();
        } catch (Exception e) {
        }
    }
}

这是我的连接和查询:我的所有数据库连接几乎与此相同:

public void addLoadingDock(LoadingDock loadingDock) {
    loadingDocks.add(loadingDock);

    Storage.connectToDatabase();

    PreparedStatement s;
    try {
        String query = "INSERT INTO LoadingDocks(dock_no, active, product_type_id) VALUES (?, ?, ?);";
        s = Storage.connection.prepareStatement(query,
                Statement.RETURN_GENERATED_KEYS);
        s.setInt(1, loadingDock.getDockNo());
        s.setBoolean(2, loadingDock.getActive());
        s.setInt(3, loadingDock.getProductType().getId());
        int rows = s.executeUpdate();
        Storage.connection.commit();
        System.out.println(rows + " row(s) created in database");
        ResultSet generatedKeys;
        generatedKeys = s.getGeneratedKeys();
        if (generatedKeys.next()) {
            loadingDock.setId(generatedKeys.getInt(1));
        } else {
            throw new SQLException(
                    "Creating LoadingDock failed, no generated key obtained.");
        }
        generatedKeys.close();
        s.close();
    } catch (Exception e) {
        System.err.println("Error adding LoadingDock. Details: " + e);
        try {
            Storage.connection.rollback();
        } catch (SQLException e1) {
            System.err.println("Error on rollback. Details: " + e1);
        }
    } finally {
        Storage.disconnectDatabase();
    }
}

有一刻,程序会遇到太多的连接问题。

请告诉我,连接有什么问题。我没有正确关闭它们的地方?或任何其他问题。

2 个答案:

答案 0 :(得分:2)

有两件事突然袭来......

  1. 你应该避免以这种方式使用static ......
  2. 在创建之前,您永远不会检查Connection是否为null,因此您可能仍然在运行恶意连接,例如......
  3. 如果你有两段代码创建了一个连接实例,而第二段代码是在第一个关闭之前创建的,那么只会放置Connection的第二个实例

    Storage.connectToDatabase();
    //...
    Storage.connectToDatabase();
    //...
    Storage.disconnectDatabase();
    

    您可以首先检查null中的connectToDatabase,例如

    public static void connectToDatabase() {
        if (Storage.connection == null) {
            try {
                String userName = "root";
                String password = "mysql";
                String url = "jdbc:mysql://localhost/secondsemesterprojectdanishcrowncaos";
                Class.forName("com.mysql.jdbc.Driver").newInstance();
                Storage.connection = DriverManager.getConnection(url, userName,
                        password);
                Storage.connection
                        .setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
                Storage.connection.setAutoCommit(false);
            } catch (Exception e) {
                System.err.println("Cannot connect to database server." + e);
            }
        }
    }
    

    为了克服static的使用,您可以使用单个模式,例如......

    public enum Storage {
    
        INSTANCE;
    
        private static Connection connection = null;
    
        /**
         * Gets the database connection.
         */
        public Connection getConnection() {
            return connection;
        }
    
        /**
         * Connects to the database.
         */
        public void connectToDatabase() {
            if (connection == null) {
                try {
                    String userName = "root";
                    String password = "mysql";
                    String url = "jdbc:mysql://localhost/secondsemesterprojectdanishcrowncaos";
                    Class.forName("com.mysql.jdbc.Driver").newInstance();
                    connection = DriverManager.getConnection(url, userName,
                            password);
                    connection
                            .setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
                    connection.setAutoCommit(false);
                } catch (Exception e) {
                    System.err.println("Cannot connect to database server." + e);
                }
            }
        }
    
        /**
         * Terminates the database connection.
         */
        public void disconnectDatabase() {
            if (connection != null) {
                try {
                    connection.close();
                } catch (Exception e) {
                }
            }
        }
    }
    

    这保证了Storage的单个实例,如果仔细完成,则可以更好地管理Connection

    另一种选择是使用某种连接池,这样就可以为你管理连接......

答案 1 :(得分:2)

使用连接池。有许多可用的,但c3p0bonecp很受欢迎。连接池将允许您更轻松地重用数据库连接,这样您就不会耗尽最大数量的" open"资源。