簡體   English   中英

准備好的語句以及連接池

[英]Prepared Statements along with Connection Pooling

我有一個關於Prepared Statement的一般用法以及連接池的問題。

准備好的語句通常僅與一個連接相關聯。在我們的應用程序中,PreparedStatement在啟動時創建並在稍后執行。

如果在執行某些特定的預准備語句時,與准備好的語句關聯的連接正忙於執行除了如何執行此必需語句之外的其他語句。此語句將等待連接獲得釋放,或者此語句將優先於執行?

更新

我已經使用Apache derby數據庫跟隨SLEEP()函數測試了這一點,該數據庫在類TimeHandlingTest中調用java函數sleep。

CREATE FUNCTION SLEEP()返回INTEGER LANGUAGE JAVA PARAMETER STYLE JAVA NO SQL EXTERNAL NAME'com.derby.test.TimeHandlingTest.sleep';

並從一個連接中創建了兩個預處理語句,並從一個預處理語句中調用了Sleep()函數,並使用其他簡單的sql select.Simple sql select花了幾乎相同的時間(10s),其中第一個預處理語句正在休眠。這意味着一個連接對象不能用於一次執行多個准備好的聲明。如果我錯了,請糾正我。

如果您打算使用PreparedStatement則無法將Connection返回到池。

換句話說:您只能使用從當前具有的Connection構造的PreparedStatement

PreparedStatement的值在於數據庫本身為語句創建執行計划的能力,該語句可以重用於任意參數,因此本質上是通用的(當然,這需要您在語句中使用參數,例如

PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES
                               SET SALARY = ? WHERE ID = ?");
pstmt.setBigDecimal(1, 153833.00);
pstmt.setInt(2, 110592);

另一方面,如果使用字符串連接將參數值粘貼到SQL代碼中,則數據庫將無法構建通用執行計划。 因此,如果您使用PreparedStatement或Statement,則沒有任何區別,例如

PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES
                               SET SALARY = 1200 WHERE ID = 3");

將無法使用PreparedStatements的優勢。

您的問題意味着,您希望重用PreparedStatement對象,這是不必要的。 當然,如果您可以使用PreparedStatement對象來更新多個值等,則可以更有效地使用資源。 然而,PreparedStatement的生命周期(或至少有用的生命周期)與Connection相關聯,因此如果調用conn.close(),則PreparedStatement將變得無用。 然而,池化情況下的大多數優秀驅動程序再次重用相同的PreparedStatement對象。 簡而言之,不要獨立於連接緩存PreparedStatement。

假設這是一個多線程應用程序, Connection對象通常在任何時刻與單個線程相關聯。 線程獲取的Connection對象在關閉之前不會返回到池中。 這既適用於邏輯連接包裝器(通常由應用程序服務器管理的DataSource返回),也適用於應用程序,也適用於物理連接。 此外,物理連接可以跨多個邏輯連接共享,只要它們是同一事務的一部分即可。

這意味着如果向您的應用程序返回邏輯連接句柄,則基礎物理連接不必相同且正在爭用(除非它是同一事務的一部分)。 如果您的應用程序需要處理並發用戶而不會有任何麻煩,那么將在每個啟動事務的線程中創建一個Connection對象,並且不會跨線程爭用該對象。 在引擎蓋下,池中的不同物理連接將跨多個線程執行與准備好的語句關聯的SQL查詢,同樣沒有任何爭用。

這聽起來像是一種使用連接池的不尋常方式。 即使連接在池中,它們也應該一次僅由一個線程使用。 我傾向於創建准備好的語句並使用它非常接近創建點。 此外,一些JDBC驅動程序現在支持Statement緩存,這減少了以這種方式使用它的開銷。

解決此問題的一種方法是維護連接映射到預准備語句的緩存。 從池中獲取連接時,檢查它是否映射到要執行的預准備語句。 如果沒有,請將准備好的語句傳遞給JDBC驅動程序,以便編譯它。 然后將其映射到連接。 這種方法的缺點是多個連接可能會獲得相同預處理語句的副本。 但似乎這是一些J2EE服務器所做的

暫無
暫無

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

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