2011-06-13 47 views
3

基於這篇文章http://www.adam-bien.com/roller/abien/entry/ejb_3_1_killed_the我使用我的應用程序@Named @Stateless bean與數據庫進行通信(在此注入EntityManager)並在jsf頁面上顯示信息。從Java EE 5開始,這非常便利,但我有一個問題。我可以使用具有CDI的EJB Stateless Bean來維護用戶會話嗎?

使用這些bean來維護用戶會話(購物車等)是否安全?我讀了一本關於ejb 3.0的書,我知道相同的無狀態bean可以與許多客戶端一起使用。

與所有ejb功能(交易,線程安全等)一起使用託管bean的最佳方法是什麼?我的意思是與Java EE 5中的實現+ ejb注入相比,託管bean + ejb接口還有其他方法嗎?

我使用GlassFish 3.1 WebProfile

+0

感謝您的回答,那麼我應該使用@Named @Stateful還是jsf會話?哪個更好/輕量級?當用戶關閉瀏覽器和ejb會話時,jsf會話結束? – m1m 2011-06-13 10:08:42

+0

或者可能將ENtityManager注入ManagedBean?它安全嗎? – m1m 2011-06-13 10:15:23

+1

當用戶關閉瀏覽器時,EJB會話不一定會結束,但Web用戶將無法在稍後再次與EJB會話連接。 EJB代理通常保存在http會話,對話或視圖範圍內,當主要http會話結束時,這些都會被銷燬。 – 2011-06-13 12:26:31

回答

6

無狀態bean無法維護購物車或會話;這就是「無國籍」的意思。

您需要有狀態的EJB或在Web層中執行此操作。這些是會話維護的唯一地點。

10

添加到duffymo的建議;使用有狀態會話bean與使用HTTP會話相比,還有一些其他注意事項。

HTTP會話基本上有一個像結構的地圖。它直接適用於會話中的所有線程(請求)。這使得操縱幾個項目成爲相對不安全的行爲。可以在會話本身上進行同步,但這是一項風險很大的操作,可能會使整個應用程序失效。 HTTP會話確實允許你聲明事件監聽器,它會觸發http會話的任何修改。

有狀態會話bean當然有一個bean結構。它具有一種自動同步功能,因爲只有線程可以在bean中同時處於活動狀態。通過註釋,你可以聲明其他線程是否等待(如果是這樣,等待多久),或者在併發訪問面前立即拋出異常。

通常每個用戶只有一個http會話,一個用戶可以同時使用多個有狀態會話bean。有狀態會話bean的一個特別的優點是它們有一種機制可以在某個超時後鈍化它們的狀態,這可以釋放你服務器的內存(當然是以磁盤空間爲代價的)。有狀態會話bean不直接擁有http會話所具有的事件偵聽器類型。

我認爲最初有狀態會話bean的「會話」方面是維持與遠程非Web客戶端(Swing,另一個AS等)的會話。這很像創建http會話以維持與遠程Web客戶端的會話。由於非Web客戶端可以請求並保留有狀態會話Bean的多個代理,因此Web類比實際上更類似於最近引入的conversation scope

在遠程web客戶端與服務器通話的情況下,服務器與有狀態會話bean進行內部對話,概念有很大的重疊。遠程Web客戶端只知道http會話(通過JSESSIONID),而不瞭解有狀態會話Bean的會話。因此,如果http會話丟失,您通常無法再將遠程客戶端與特定的有狀態會話bean連接起來。在這種情況下,HTTP會話總是處於領先地位,您可能還會將您的購物車項目存儲在單個(http)會話作用域bean中。

有一種特定情況,其中有狀態會話bean派上用場進行內部通信,這就是如果您需要JPA的extended persistence context。這可以在例如使用時使用。對實體的鎖定需要在請求之間持續(如果您的股票數量有限,可能對於購物車來說很方便,並且一旦他實際簽出就不想與用戶發生「缺貨」消息)。

相關問題