|
||||
1.0 其他語言 |
||||
3.3.4 每個網路請求一個事務 transaction per request |
||||
|
在 EJB 中,事務定義在業務函數級別。這並沒有什麼錯,但是想保證程式員在一個請求中不呼叫超過一個 EJB 函數,並不容易。大多數情況下,程式員都會寫出這樣的代碼。這會導致事務以意料之外的方式執行。 VelocityWeb 采用了另外一種方式,那就是每個網路請求一個事務 TRANSACTION_PER_REQUEST。透過在請求分發器上定義事務級別,整個框架可以在需要事務的時候啟動事務。 在這種方式下,不管一個請求中,呼叫了多少個業務函數,VelocityWeb 都會保證它們執行在一個事務里。 程式員不需要關注事務管理,VelocityWeb 會處理好這部份工作。 將事務級別定義在請求上,而不是業務函數上,是否恰當? 答案是"YES"。 大多數情況下,整個專案/產品中,只有兩種事務級別︰查詢(沒有事務,TRANSACTION_NONE), 更新(大多數使用 TRANSACTION_READ_COMMITTED)。 對每一個請求,比如,增加使用者,修改使用者,刪除使用者,尋找使用者,查看使用者,即使是業務方面的人都可以告訴我們,它是一個查詢請求還是一個更新請求。這直接導致了一個新的設計模式︰TRANSACTION_PER_REQUEST。我們可以這麼說,事務級別,是請求分發器的一個屬性。 可以在分發器的構造函數中呼叫 setTransactionIsolation(xx)。或者,直接寫 QueryDispatcher 或 UpdateDispatcher 的子類。
public class StoreMainDispatcher extends QueryDispatcher { Log log = LogFactory.getLog(this.getClass()); public StoreMainDispatcher() { this.setHtmlTemplateFileName("system/store_main.htm"); this.setPageTitle("Default Store Home"); } public String getUrlId() { return "store_main"; } public boolean process(HttpServletRequest request, WebAppContext context, Controller controller) throws Exception { log.debug("process"); context.put("view_category_url", DispatcherTreeManager.getUrl(ViewCategoryDispatcher.class)); return true; } } |
|||