2009年4月11日
2009年4月2日
private UserService userService = null;
private UserService() {}
public static UserService getInstance() {
if(userService == null) {
synchronized(UserService.class) {
if(userService == null) {userService = new UserService();}
}
}
return userService;
}
}
首先,當DAO層Catch到SQL異常,應該讓相應的事務回滾,并繼續拋出該異常
conn.rollback();
throw e;
在方法聲明時throws這個異常;
第二,在Service層調用到Dao層時,try catch這個異常,在catch住中把它處理為RuntimeException異常;
處理過程是:自定義一個繼承自RuntimeException的異常類AppRuntimeException;
catch(){
new AppRuntimeException();
}
第三,在Servlet中使用配置文件web.xml注冊這個Exception,或者注冊為RuntimeException,調用Service時,如果發生這個異常,則會跳轉到相關的友好的面向用戶的錯誤頁面;
注意:如果頁面未轉向,則可能是反射過程中拋出的其他異常截獲了我們自定義的這個RuntimeException,我們可以在這個異常中做出處理,讓它轉換為我們自定義的RuntimeException;
第四,以上我們只是簡單的處理了異常,一般正常的與業務相關的異常;
2009年4月1日
為了解決一個事務的多個數據模型使用多個Connection的情況,首先想到的是在執行每個原子級數據模型的操作的時候直接在方法的參數中傳進來一個Connection,下一個操作也把這個同一個Connection傳進來,但是這樣帶來的問題有兩個,一是,設計問題,針對數據庫的操作DAO的方法中的參數一般都應該是針對數據庫查詢的查詢條件,把Connection放在這里作為參數顯然不合適;第二,Connection作為多個數據模型操作的共享,只在最后一個操作中才被關閉,這對于如果只有單個操作的事務執行時,Connection將不會被關閉。
為了解決這些問題,需要有一個專門生產Connection的類,供DAO層各方法調用,但是幾個方法如果是同一事務時,他們拿到的Connection應該是同一個;
由此,生產Connection的類,有兩個方法,一是生產Connecton,放到一個容器中,即set方法,二是得到Conneciton,即get方法;
當同一事務的多個方法調用時,拿到同一個容器中的Connection即可保證他們拿到的是同一個Connection對象;
為了保證拿到的是同一個容器,使用類級別的變量,static Hashtable;
采取static類變量的方式,解決了以上引起的設計問題?
因為static的方法是位于方法區中的,多個線程共享,所以又引發了線程不安全的問題;
所以使用API中的ThreadLocal類型的變量,使得多個線程各自擁有自己的一個容器,從而解決了線程不安全的問題。