2015-01-02 79 views
0

我無法弄清楚如何在有狀態Bean中執行EJB3兼容的串行處理。也就是說,只有一個特定時刻只能有一個線程可以訪問的實例。我可以添加​​的方法,但這些都是不符合標準的補充,如:EJB 3.0線程

閱讀本:

無論如何,只有一個線程應該訪問它,所以感到困惑。

我這樣說的:

,它說:

通過JBoss的EJB 3.0提供了一個擴展是@ org.jboss的概念。 annotation.ejb.Service註釋的bean。它們是單身bean,並且不是合併的,因此服務器中只存在一個bean實例。它們可以同時擁有@Remote和@Local接口,以便Java客戶端可以訪問它們。當不同的客戶端查找@Service Bean的接口時,所有客戶端將在服務器上的同一個bean實例上工作。

但是,它並沒有說明多個線程是否可以同時訪問它。也就是說,如果我有10個客戶端獲得了此服務實例的遠程代理,他們可以調用一個方法10次。它們中的每一個仍將在同一個bean實例上操作,但該方法將被多次調用。這是一個測試結果,我無法在API /文檔中找到任何具體的說法。

這使得它不能用於某些情況下,例如,生產者/消費者,我需要按順序處理事情,基本上是單線程的。我錯過了什麼嗎?如何在不訴諸其他事情的情況下實現串行處理(例如使用數據庫鎖定或MDX等)?

順便說一句,代碼簡單/往常一樣 - 這裏的要點是:

public interface MyService { 
    public void callMe(); 
} 

@Service 
@Remote(MyService.class) 
public class MyServiceImpl implements MyService { 
    private Logger logger = Logger.getLogger(MyService.class); 

    public void callMe() { 
    logger.info("called entry"); 
    try { 
     Thread.sleep(1000); // simulate work 
    } catch(InterruptedException e) { 
    } 
    logger.info("called exit"); 
    } 
} 

希望我沒有做錯別字,但你的想法。不能去EJB 3.1嘗試使用@Singleton,使用古老的JBoss 4.2.1,不能升級:(當我運行上面的代碼時,我得到了幾條入口語句,然後它們都等待一秒鐘,然後它們全部退出。如果我要處理一些狀態(並且我讀了@Service是一個有狀態的bean),那麼所有的都會被修改。

我想過使用@PoolClass(value = org.jboss.ejb3.StrictMaxPool.class, maxSize = 1),但是這對於任何事情都沒有幫助,因爲它只是一個實例,只是多次訪問您是否有任何線索或方向?

當然 - 將​​添加到callMe方法實際上解決了問題,所以不確定要考慮這一切。服務器配置錯誤?

+1

好像XY問題給我。你想要依次處理什麼? –

+0

@JeanLogeart夠公平的。想一想 - 我有一個需要每小時調用一次的傳統服務。由於各種原因必須完成一次。當調用上面的'callMe'方法時,它會被懶惰地完成。如何確保a)我做了一次b)我沒有違反EJB3「不同步觸摸」限制? –

+0

我的回答,我的壞,我太快,跳到你指出的行爲。 1)從你的資料來看,「服務」是你做的最後一件事; 「唯一的一個實例」指向它被所有線程重用。 2)嘗試使用Session Bean將池大小限制爲1,https://developer.jboss.org/thread/34588?tstart=0從它應該工作的鏈接開始,3)JMS仍然是值得考慮的選項。 – SJuan76

回答

0

如何實現串行處理而不訴諸其他事情 (例如使用數據庫鎖定或MDX等)?

雖然無法確定消息是否已發送給使用者(僅限於隊列),但是您可以使用「點對點消息傳遞樣式」進行JMS。

Java EE 5 tutorial p2p JMS

jboss 4 JMS p2p example

+0

謝謝JohnRambo。 MDX是JMS--我想避免這種情況。 –

+0

您需要的是@ @ Singleton與'@Lock(WRITE)'方法,但它是在EJB3.1中引入的。我認爲'同步'方法或內部監視器/鎖定將是最佳解決方案。也考慮超時。 – ptrwis