簡體   English   中英

我是否正確關閉了數據庫連接? JDBC-DBCP

[英]Am I closing the DB connection correctly? JDBC - DBCP

關閉preparedStatement也會關閉並將連接返回到連接池嗎?

public void insertProjectIntoDatabase(Project project) {
        String insertProjectIntoDatabase =
                "INSERT INTO projects(Project_Id, Project_Name, Project_StartDate, Deadline) " +
                        "VALUES (?, ?, ?, ?)";
        try {
            preparedStatement = DBCPDataSource.getConnection().prepareStatement(insertProjectIntoDatabase);
            preparedStatement.setInt(1, project.getProjectId());
            preparedStatement.setString(2, project.getName());
            preparedStatement.setDate(3, java.sql.Date.valueOf(project.getStartDate()));
            preparedStatement.setDate(4, java.sql.Date.valueOf(project.getDeadline()));
            preparedStatement.execute();

            preparedStatement.close();
        }
        catch (SQLException e)
        {
            System.out.println("Error happened in ProjectRepository at insertProjectIntoDatabase(): " + e.getMessage());
        }
    }

獎金問題:

每次 object 需要一個 Singleton 連接和連接池時,我都創建了用於創建新連接的性能測試。

Singleton - 最快

每次創建一個新連接 - 比上面的慢(1.2s)

連接池 - 最慢(第一次連接 - 比上述慢 2-3 秒,以下測試比上述慢 0.4 秒)

我正在使用 Apache Commons DBCP 作為連接池。

我認為使用連接池會比 Singleton 連接慢一點。

我做錯了什么嗎?

您問:

關閉preparedStatement也會關閉並將連接返回到連接池嗎?

文檔開始:

立即釋放此 Statement 對象的數據庫和 JDBC 資源,而不是等待它自動關閉時發生。 通常最好在使用完資源后立即釋放資源,以避免占用數據庫資源。

對已關閉的 Statement object 調用方法 close 無效。

注意:當 Statement object 關閉時,其當前的 ResultSet object(如果存在)也將關閉。

沒有提到關閉連接。

試試直覺:我們是否曾經在 SQL 中運行多個語句? 是的,很明顯。 所以從邏輯上講,連接需要在多個語句中存活下來才能有用。

最后:自己嘗試,經驗測試。 在調用Statement#close之后調用Connection#isOpen

➥ 不,關閉語句不會關閉連接。

對於最簡單的代碼,學習使用try-with-resources語法來自動關閉您的數據庫資源,例如結果集、語句和連接。 您會在此站點上找到許多此類代碼的示例,包括我編寫的一些示例。

至於連接池,是的,對從池中檢索到的連接調用close會導致連接 object 被返回到池中。 池可以選擇重用連接,或者池可以選擇關閉連接。 (不是我們關心的問題。)

連接池的唯一要點是速度。 如果打開與數據庫的連接需要大量時間,我們可以通過重用現有連接來節省時間。 生成和重用連接是連接池的工作。

如果連接池在您的測試中顯示最慢的結果,那么您的連接池或您的測試存在嚴重錯誤 您沒有向我們透露您的測試,因此我們無法提供幫助。 注意:正如Marmite Bomber 所評論的,請確保您的測試包括建立連接池所需的時間。

坦率地說,根據我的經驗,我發現打開數據庫連接並不需要很長時間。 此外,正確實施連接池所涉及的細節是復雜和危險的,這從失敗和放棄的連接池實施項目列表中可以看出。 再加上諸如事務在檢索到的連接上保持打開狀態等固有風險,導致我避免使用連接池。 我認為在收集實際問題的證據之前使用連接池是過早優化的一種情況。

我建議使用接口DataSource的實現作為屏蔽代碼的 rest 的方法,無論您是否正在使用池並隱藏您當前正在使用的池實現。 使用DataSource可以讓您靈活地在使用或不使用連接池之間進行切換,以及在池之間進行切換。 這些更改成為部署選擇,無需更改您的應用程序編程。

池旨在提高性能,而不是降低性能。 DBCP 是幼稚的、復雜的和過時的。 我認為它不適合生產應用程序,尤其是當有這么多驅動程序在其 DataSource 本地支持池時。 在對數據庫進行新連接嘗試的整個過程中,整個池都會被鎖定。 因此,如果您的數據庫發生了導致連接緩慢或超時的問題,則其他線程在嘗試將連接返回到池時會被阻止——即使它們是使用數據庫完成的。 甚至 C3PO 的表現也很糟糕。 請嘗試使用兩個連接池之一 tomcat_connection_poolHikariCP

如果您已正確關閉連接,現在進入問題的主要部分? 每當您使用連接池並從池中獲取可用連接時,您無需關閉在 Dao 層中獲取的連接。 池管理您創建的連接,並且池借出的每個連接都有與之關聯的超時,在此之前它必須返回池。 當池關閉時,所有連接也會關閉。

有關如何在連接池中配置這些屬性的更多信息。 請檢查每個連接池的上述鏈接。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM