2011-03-23 51 views
4

我們的portlet保持在HttpSession中,這是由同一個會話的所有請求處理線程共享的狀態。的Portlet的是,HttpSession和線程安全

該Portlet規範(JSR-168)寫道:

PLT.5.2.4.3多線程問題在處理請求

portlet容器處理併發 執行併發請求到相同的portlet不同線程上的請求處理方法。 Portlet開發人員必須 設計自己的portlet在任何特定的時間來處理多個線程從 processActionrender方法中併發執行。

我不知道我應該如何實現呢?當然,我可以使用同步既processActionrender過程中實現相互排斥,但我不知道怎樣才能強制執行請求處理的原子作爲一個整體。我特別擔心以下情形:

  • 線程1執行processAction,將數據加載到會話後呈現
  • 線程2執行processAction,從會話
  • 線程1執行render丟棄數據,從會話中讀取要呈現的數據,並拋出NullPointerException,因爲準備好的數據不再存在...

這種情況通常如何防止?特別是,當使用JBoss Portlet橋接器來調整JSF到Portlet環境時?

回答

1

我想說,如果有兩個Portlet在相同的數據上運行,尤其是一個讀取它而另一個刪除它,那麼最有可能是設計中存在嚴重缺陷。

你可能再要存儲每個Portlet /線程,即如果數據讀取portlet1一些數據,你應該寫鎖定,直到讀完成,採用了獨特的鑰匙放進了會議。

如果是合法的,刪除了應該呈現的數據,那麼你應該考慮這一點,在render再次檢查。

+0

您誤解了:它是同一個portlet,服務器同時處理兩個請求,因爲用戶在前一個點擊仍在處理中時單擊第二個按鈕。不,狀態必須在請求中可見(因爲後續請求可能在相同的數據上運行,我不想從數據庫重新加載它),所以我不能將它綁定到線程。 – meriton 2011-03-23 13:18:38

+1

嗯,這取決於用例,但我不會允許用戶在當前完成之前觸發另一個操作。例如:用戶加載一些數據,然後點擊'刪除'而沒有真正看到它。從商業角度來看,這很容易出錯。如果這仍然可以發生,那麼你需要考慮到這一點 - 比如在渲染時檢查數據仍在那裏,並在操作期間鎖定它。 – Thomas 2011-03-23 13:25:40

+0

所以,即使我設法同步服務器上的整個請求處理,這仍然會使實際的業務事務處於原子狀態,並且使業務事務處於原子狀態的任何事情都會平凡地解決服務器上的併發問題。這是一個很好的觀點,因此我會考慮在客戶端做一些事情。非常感謝! – meriton 2011-03-23 14:19:50