我無法弄清楚如何在有狀態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方法實際上解決了問題,所以不確定要考慮這一切。服務器配置錯誤?
好像XY問題給我。你想要依次處理什麼? –
@JeanLogeart夠公平的。想一想 - 我有一個需要每小時調用一次的傳統服務。由於各種原因必須完成一次。當調用上面的'callMe'方法時,它會被懶惰地完成。如何確保a)我做了一次b)我沒有違反EJB3「不同步觸摸」限制? –
我的回答,我的壞,我太快,跳到你指出的行爲。 1)從你的資料來看,「服務」是你做的最後一件事; 「唯一的一個實例」指向它被所有線程重用。 2)嘗試使用Session Bean將池大小限制爲1,https://developer.jboss.org/thread/34588?tstart=0從它應該工作的鏈接開始,3)JMS仍然是值得考慮的選項。 – SJuan76