2011-12-23 50 views
4

假設您有一個具有EJB3/JPA和JSF堆棧的Web應用程序。 AFAIK你可以使用不同的託管bean設計你的屏幕,例如,假設一個HeaderBean和一個ListingBean。由於有在EJB3據我所知沒有OSIF模式,不同的交易有多少在下面的僞代碼執行:典型的EJB3/JPA/JSF中的事務範圍是什麼?

@ManagedBean 
class HeaderBean { 
    @PreConstruct 
    load(){ 
    // enters transaction boundary, probably will create a new tx 
    headerInfo = ejb.loadFromDb(); 
    } 
} 

@ManagedBean 
class ListingBean{ 
    @PreConstruct() 
    list(){ 
    // enters transaction boundary, probably will NOT join the headerBean tx 
    List<Data> listing = eao.loadFromDb(0, 20); 
    } 
} 

AFAIK當你離開EJB層的所有交易承諾;所以如果我從表示層調用兩個不同的SLSBs,它將運行在兩個不同的事務中(並且可能會破壞我的期望吧?)。


澄清:我所知道的EJB3交易行爲,如required, never, requires_new等。我的問題更多地是關於View-First(如JSF)如何促進這種設計,其中屏幕數據可能跨越多個事務,因此可能不準確。

我更喜歡較長的交易,但數據比短交易更正確,但數據不正確。我在想,如果像jBoss Seam這樣的新框架以某種方式促進了這一點,或者提供了另一種設計(例如:Open-Session-In-View模式)。

+1

CMT僅在EJB上可用。 'loadFromDb'方法的名稱甚至不像它需要事務。 – 2011-12-23 15:58:35

回答

2

有一些選項可以控制EJB的事務行爲。通常他們有一個「需要一個事務」的設置,這樣如果一個bean被調用了一個事務,那麼這個bean的工作就包含在已經建立的事務中,否則一個事務將在bean返回時啓動並完成。

在您的代碼中,在進入EJB時沒有適當的事務,因此您從EJB返回時說任何事務都已解決。

雖然這看起來有潛在的問題,您可能會得到不一致的數據視圖,但我認爲這種行爲是可取的。我們希望在一個事務中花費的時間很短 - 否則數據庫鎖定會持續很長時間,因此併發會受到影響。

EJB層應該被視爲提供原子服務,並據此設計和使用。我不知道我是否正確讀取了你的代碼,但是對Header和Body分別使用不同的訪問方法可能不是最好的設計。如果您需要在頭文件和正文之間進行一致性讀取,則一次調用中的所有數據可能更可取,並且實際上可以在單個數據庫交互中更高效地完成。

- 添加--- 在您的問題中,您已澄清,如果使用簡單的JSF技術進行編碼將使用單獨的事務,則確實擔心屏幕不同部分之間的一致性。

在我看來,當這種不一致或者極不可能或不可避免時,默認的JSF方法是合適的。例子: 1)。不太可能:查詢歷史數據,昨天交易總數和昨天交易清單。在歷史不能改變的系統中,這種單獨的查詢將是一致的。 2)。不可避免:總結來自一個系統,來自不同系統的細節,兩個系統之間沒有事務協調,我們無法保證一致性。我們只需要向用戶展示這兩個視圖可能略有失調。

如果你真的想要一致性使用不同的方法,獲取單個請求中的所有數據並保存它(例如在會話或請求中),然後在兩個視圖中使用它 - 如果你的視圖不應該獲取自己的數據關心這樣的事情。

我想你會發現,嘗試使用事務來保持事物的一致性會增加相當大的複雜度,並影響吞吐量。跨視圖協調事務的問題在於沒有簡單的「所有者」,如果重新組織頁面,則需要更改邏輯

+0

請檢查我的說明。 – 2011-12-23 17:37:23

+0

我已經擴展了我的答案 – djna 2011-12-23 23:00:05