2013-02-15 71 views
3

我有一個web服務,它在初始化時實例化一個帶有數據源的單個QueryRunner。它使用這個QueryRunner對象來處理來自webapp使用的多個不同servlet的所有servlet請求,並將它作爲servlet上下文屬性傳遞。 I .: .:DBUtils QueryRunner實例化

// in servlet context listener (on app initialization) 
QueryRunner myQueryRunner = new QueryRunner(myDataSource); 
myServletContext.setAttribute("queryRunner", myQueryRunner); 

// in the servlets 
QueryRunner myQueryRunner = (QueryRunner) myServletContext.getAttribute("queryRunner"); 
myQueryRunner.query(myStoredProcedure, handler, params) 

我想弄清楚如果這是一個瓶頸。 servlet是否應該用每個請求來實例化一個新的QueryRunner

四處尋找答案時,我也發現這AsyncQueryRunner。但是我更加困惑,因爲在QueryRunnerAsyncQueryRunner的API文檔中的解釋說的完全一樣。

我查看了示例here,它似乎應該實例化每個請求,但我不確定是否僅僅因爲它是示例代碼。

換句話說,使用DBUtils當QueryRunner應該我:

  1. 使用單一QueryRunner實例爲每個請求? (我現在在做什麼 )
  2. 用每個servlet請求實例化一個新的QueryRunner
  3. 每個請求使用一個單一的AsyncQueryRunner實例?
+0

我想弄清楚這是否是一個瓶頸。這是不可能的。QueryRunner是一個線程安全的類,您可以爲所有請求使用一個QueryRunner。 AsyncQueryRunner使用ThreadPool來處理每個查詢,但它不是正常情況,它只用於長查詢花費。 – 2015-04-09 05:57:18

回答

4

QueryRunner是一個線程安全類,因爲它是無狀態的,因此您可以在多線程環境中使用單個實例,而不會出現任何問題。

所有方法都是自包含的,因此不需要對方法訪問進行同步,因此您也可以排除瓶頸。

我在生產環境中沒有問題地使用它,但是我的實現遵循模式「用每個語句實例化一個新的QueryRunner」,因爲它是一個沒有狀態的委託類,所以沒有大量初始化並且沒有堆消耗,我避免使用單例或其他共享實例來存儲這種類型的類。

AsyncQueryRunner也是線程安全的,但其用途和用法完全不同(請參閱http://commons.apache.org/proper/commons-dbutils/examples.html)。它用於爲長時間運行的語句創建非阻塞呼叫。如果您的業務層需要異步,這可能很有用。

結論:從多個線程(?每個請求一個線程)

  • 採用單QueryRunner實例沒有counterindication也沒什麼adavantages,但需要的代碼一點點的地方來管理這種情況下
  • 爲每個線程使用新的QueryRunner實例,甚至爲每個要通過它委派的語句使用新的QueryRunner實例有兩個主要優點:簡單和本地化的使用,如果不需要它們,則內存中沒有實例。
  • AsyncQueryRunner需要繁瑣的查詢響應管理,因此只有在業務代碼中需要異步行爲時才能使用它。