簡體   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