繁体   English   中英

我是否正确关闭了这个 Oracle 池连接?

[英]Am I closing this Oracle pooled connection correctly?

我正在尝试在 Java 中为我的 web 应用程序使用池连接。 我正在使用 Oracle 数据库,这是我的代码:

public class DatabaseHandler
{

    static private Connection m_database = null;

    static private OracleConnectionPoolDataSource pooledSource = null;

    /**
     * Attempts to open an Oracle database located at the specified serverName and port.
     * @param serverName Address of the server.
     * @param portNumber Port to connect to.
     * @param sid SID of the server.
     * @param userName Username to login with.
     * @param password Password to login with.
     * @throws WebApplicationException with response code 500 Internal Server Error.
     */
    static public void openDatabase(String userName, String password,String serverName,int portNumber, String sid)
    throws WebApplicationException
    {
        try
        {
            // Load the JDBC driver
            String driverName = "oracle.jdbc.driver.OracleDriver";
            Class.forName(driverName);

            // Create a connection to the database
            String url = "jdbc:oracle:thin:@" + serverName + ":" + portNumber + ":" + sid;
            pooledSource = new OracleConnectionPoolDataSource();

            pooledSource.setUser(userName);
            pooledSource.setURL(url);
            pooledSource.setPassword(password);
            m_database = pooledSource.getConnection();

        }
        catch (ClassNotFoundException e) 
        {
            // Could not find the database driver
            throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
        }
        catch (SQLException e) 
        {
            // Could not connect to the database
            throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
        }
    }


    /**
     * Attempts to execute the specified SQL query.
     * @throws WebApplicationException with a response code of Bad Request
     * if the query is invalid SQL.
     */
    static public ResultSet makeQuery(String query) throws WebApplicationException
    {
        ResultSet rs = null;
        if (m_database != null)
        {
            try 
            {
                Statement stmt = m_database.createStatement();
                rs = stmt.executeQuery(query);
            }
            catch (SQLException e)
            {
                // invalid query
                System.out.println(query);
                throw new WebApplicationException(Response.Status.BAD_REQUEST);
            }
        }        
        return rs;
    }

    /**
     * Attempts to close the database. 
     * @throws WebApplicationException with a response code of  500 Server error
     */
    static public void closeDatbase() throws WebApplicationException
    {
        try
        {
            m_database.close();
            pooledSource.close();
        }
        catch(SQLException e)
        {
            throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
        }
    }
}

我在 Eclipse 中执行此操作,并且我警告说不推荐使用pooledSource.close() 我以前从未使用过池连接,我只是想确保我做的一切都是正确的。 有没有更好的方法来关闭 Oracle 池资源?

不推荐使用的方法意味着不应使用此方法。 在未来的版本中,可以完全清除close()方法。 我建议删除pooledSource.close()

另外,我建议不要有ConnectionDataSource的 static 实例,因为您需要根据请求建立连接,并且不要在整个应用程序中保持连接。 始终先关闭ResultSet ,然后再关闭Connection ,并通过将它们添加到finally块中来保证关闭。

  1. 连接必须关闭才能返回到池中。
  2. 始终在 finally 块中关闭您的连接。
  3. 永远不要将连接引用作为 class 成员 - 这是容易出错和糟糕的设计。 应尽可能晚地获取连接并尽快释放。 作为 class 成员持有类似的东西是没有意义的。
  4. 关闭使用它们的连接。 您的代码在这里再次容易出错。 如果您忘记调用closeDatabase()您正在泄漏连接。

注意:这里不要乱关闭connection和关闭connection pool

因为这里请求了一些用于正确和良好连接处理的代码:

public void doSomethingWithDb(Connection con, ...) {
    boolean release = (con == null);

    try {
        con = PersistenceUtils.getConnection(con); //static helper return a new conenction from pool when provided con==null otherwise simply returns the given con

        //do something

        if(release) {
            con.commit();
        }
    }
    catch(SQLException e) {
        //handle errors, i.e. calling con.rollback() but be sure to check for con!=null before. Again maybe null-safe static helper method here.
    }
    finally {
        if(release && con!=null){
            con.close();
        }
    }
}

我使用 Connection 作为方法参数,以便能够在一个数据库事务中调用许多此类方法。 但是您始终可以将null作为 Connection 的第一个参数,并且该方法为您从池中获取连接。

当您在“DB-Method”中调用另一个“DB-Method”时,您只需提供与底层方法的连接 - 这样您就可以在一个事务中拥有所有内容。

如您所见,正确的 JDBC 代码会产生很多样板代码。 在第一步中,您可以通过实现像 PersistenceUtils 这样的实用程序类来减少它,它提供 static 空安全方法,如 commit(Connection)、rollback(Connection)、getConnection(Connection)、close(Connection)... 这样你就得到了摆脱所有空检查,您也可以在其中包含日志记录或其他内容。

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM