我有一個主控制器servlet,其中我實例化數據源。 servlet打開和關閉連接。主要是,servlet使用「工廠模式」從應用程序實例化命令。這裏是一些代碼來解釋:來自jndi數據源/連接池的jdbc連接的「惰性初始化」:可行性
public void init() throws ServletException {
super.init();
try {
datasource =(DataSource) getServletContext().getAttribute("DBCPool");
}
catch (Exception e) {
}
}
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//some code...
Connection connection = null;
if(cmd.mightNeedLazyLoadingAConnection)
{
connection = null;
}
else
connection = getConnection();//where getConnection is a method: datasource.getconnection();
//now a command (a java class) is instantied, to which the "null" CONNECTION obj is passed as parameter
cmdFactory.getInstance().getCommand(Cmd).execute(tsk,connection);
//some code
//Then wherever there is catch exception i close() the connection
// and it is always closed in finally
finally {
if(connection!=null)
connection.close()
}
}
現在,這款擁有問題對於第一種情況,即連接= NULL,因爲它從來沒有關閉在「終於」部分連接(解釋了爲什麼在更新下面)。
「連接= NULL」對於其中命令可能需要打開,因爲它正在尋求在identity map緩存中的數據數據庫連接的情況。
我試圖通過「連接」 OBJ作爲.execute一個 「空」 參數(TSK,連接);,然後在相應的Java類打開連接如果需要
- >它確實打開命令內部的連接,然而,當處理返回到的servlet:「連接」是null作爲因而不關閉。
我能做些什麼來使「連接」 obj的值得到更新,以便當返回到servlet時它不再是「空」,我可以關閉它?
我通常喜歡使用打開/關閉分貝連接的控制器servlet,所以這將是應對這種情況的,你必須做一些「懶加載」一個數據庫連接的最佳方式從池中同時保持打開/關閉的db連接分配給servlet?
更新(解釋進一步):
- 說,我有一個命令:X.java
- 該命令可能/可能不會需要一個數據庫連接(取決於如果數據搜索是否在身份地圖或不)
我想要的系統是:
(1)「客戶請求」
(2)--->「的Servlet」: command.execute(連接)//其中連接= NULL現在
( 3)--->「命令X」:我需要去數據庫或記錄是在身份地圖嗎?
(3。一)在需要的地方去數據庫案例:
(3.A.1)連接=的DataSource.getConnection
(3.A.2)去獲取數據
(4) - - >回與Servlet:接近「的Servlet」
眼下的「連接」這是工作,直到(3.A.2),但一旦回到(4)看來,連接仍然是「空「,因此代碼:
finally {
if(connection!=null)
connection.close()
}
不起作用(不關閉連接),因此數據庫池就這樣被排空。 連接 - 如何從「null」開始,在命令「X」內更改 - 將「globaly」更新爲其新值,而不僅僅是命令範圍「X」中的「更新」?
SOLUTION(S)
在您遇到相同的情況下,您可以選擇這些2的解決方案:
您可以使用LazyConnectionDataSourceProxy,由作爲mentionned @Ryan Stewart爲「乾淨的抽象」和更專業的解決方案
或者,如果你想使用下面介紹我的解決方案(基本上我實現類似於類「LazyConnectionDataSourceProxy」,但它並不像乾淨的,它具有比「LazyConnectionDataSourceProxy」細節較少抽象)
我個人解決方案,詳細說明:
- 我創建了一個「助手」類,它的構造採用了「數據源」作爲參數
- 這個輔助類有以下方法:「懶惰得到」從池連接「的CLOS e「連接
- 該類在servlet中實例化,並且在整個應用程序中需要連接池只有需要。
這是我添加的代碼/在servlet修改:
Connection connection = null;
if(cmd.mightNeedLazyLoadingAConnection)
{
helper hp = new helper(datasource);
cmdFactory.getInstance().getCommand(Cmd).execute(tsk,hp);
}
else
{
connection = getConnection();
cmdFactory.getInstance().getCommand(Cmd).execute(tsk,connection);
}
然後,在命令 「X」 表示,需要一個分貝連接我做:
Connection connection = hp.LazyGet();//Now got a connection from the pool
而這樣,當進程流程回到servlet級別時,我可以:
- 關閉
- rollback
- commit
- etc ..
所有關於helper類的hp對象。
做我從這個有什麼好處:
- 我限制所有數據庫開啓/關閉/提交/回滾在一個的地方,也就是Servlet,這是負責執行命令。
- 有案件:永遠不需要DB /總是需要DB /可能需要DB因此現在我通過1/3減少調用數據庫,這是相當多的知道數據庫調用與新的指數增長功能和新用戶註冊。
這可能不是最清潔解決辦法,但這種方式有一個額外的「不必要」的1/3數據庫調用之間,那肯定是更好。或者如果你想測試,抽象和乾淨的方法只是使用LazyConnectionDataSourceProxy。
感謝您的提示。我剛剛在幾分鐘前發佈了我的解決方案。我沒有使用框架,但我做了某種助手/代理類(檢查我的答案)。 – shadesco 2012-04-20 22:45:57
我沒有說使用框架。 'LazyConnectionDataSourceProxy'的功能與您的解決方案所描述的幾乎完全相同,只不過它隱藏了乾淨的抽象層後面的髒東西。沒有「可能需要連接」或「懶得到」的概念。你只是把它看作是一個普通的'DataSource',它提供了正常的'Connection's,你可以免費獲得懶惰。出於這些原因,這是一個相當好的選擇。 – 2012-04-21 00:06:04
我明白了..我會重新檢查一下並瞭解更多信息 – shadesco 2012-04-21 02:25:37