2015-12-14 25 views
3

我的應用程序有一個調度程序,需要每10秒運行一次以從數據庫中提取新記錄。我已經執行了ejb調度程序服務,通過以下this guide運行正常。沒有客戶端可以使用hit()方法,它只能作爲調度程序運行。EJB調度程序服務無狀態與單例

辛格爾頓唯一途徑,

@Singleton 
@Startup 
public class DataFetcherService { 
    @Schedule(second="*/10", minute="*", hour="*", persistent=true) 
    public void hit() { 
      //do some stuff 
      fetchData(); 
    } 
    public void fetchData() { 
      //Fetch new records from the database through DAO objects 
    } 
} 

有沒有,如果我用@Stateless代替@辛格爾頓有什麼區別?請建議

更新:無狀態的方法,

@Singleton 
@Startup 
public class DataFetcherService { 
    @EJB 
    DataFetcherBean dataFetcherBean; 
    @Schedule(second="*/10", minute="*", hour="*", persistent=true) 
    public void hit() { 
      dataFetcherBean.fetchData(); 
    } 
} 
@Stateless 
public class DataFetcherBean { 
    public void fetchData() { 
      //Fetch new records from the database through DAO objects 
    } 
} 

回答

3

我不是你的問題完全清楚,但如果我理解正確的話,你可以處理這個方法有兩種。如果你想要,你可以在你的@Singleton中注入你的EntityManager,然後將你的JPA相關的biz邏輯放在@Singleton的方法中,這些方法將被hit()和其他客戶端調用的其他方法調用。在這種情況下,客戶端訪問和預定訪問都將以同步方式進行。性能不是很好,但我想這就是你的架構。

另一種選擇是通過將此數據提取biz邏輯放置在其自己的@Stateless EJB中並將該EJB注入到@Singleton中來更鬆散地耦合事務。您的@Singleton然後可以從hit()和其他任何方法調用此EJB上的方法。由於@Singleton的默認容器管理併發性爲@Lock(LockType.WRITE),因此您將有效地序列化所注入EJB的所有訪問權限(只要它全部通過單例)。這種設計使事情更加鬆散耦合,但是增加了涉及的類的數量,並增加了一個無狀態的EJB,這樣就可以使用更多的資源進行彙集。這些是一些折衷。

如果您選擇第一個選項,並且您需要非同步執行所述業務邏輯,那麼您需要重構一些東西以使用EJB。

還有一件事要考慮。如果您決定僅採用@Singleton方法,則必須小心如果您需要其中一個方法調用另一個方法。在這種情況下,您將無法使用CMC(容器管理的併發),但是您將自己使用ConcurrenyManagementType.Bean並處理同步。

每次更新新的評論從OP:

@Hello - 如果你有@Stateless替換@Singleton你也會鬆動@Startup其僅適用於@Singleton豆。這對您而言可能並不重要,但它不會影響@Schedule方法,因爲在應用程序部署時可以看到並「設置」該方法。

您需要使用bean的代理調用fetchData();,或者從注入的SessionContext資源獲取或通過自注入獲得。您現在正在執行的方式是在調用預定方法時,啓動包含TX容器的容器。有時候這個問題有時候不會,但會導致細微的錯誤,這就是爲什麼它最好能確保你通過代理訪問「本地」方法。

最後,如果你使用上面的方法與@Singleton你將需要切換到Bean管理的併發性,因爲容器不會在重入的方式處理這種類型的方法獲得@Lock(LockType.WRITE)方法和會給你一個錯誤(至少這是我在Glasfish上JavaEE6中看到的行爲)。

+1

'@Lock(LockType.WRITE)'。 – Tiny

+0

NBW,我已更新該帖子。你可以看看嗎?我有2個問題:上述方法(容器管理類型)有問題嗎?我們可以用無狀態註釋替換單例嗎? – Hello

+0

@Hello - 更新我的回答對您的問題和變化。 – NBW

2

有一對夫婦的使用@Singleton和@Stateless爲您安排服務之間的差異:

  • 如果使用@Stateless然後執行註解的方法的bean實例將是完全自主的,不能被你的應用程序的其餘部分所引用。容器將在部署時創建計時器並根據計劃調用回調。如果你嘗試注入這個bean的實例,那麼你會得到它的另一個副本(沒有運行時間表)。

  • 如果使用@Singleton豆那麼你可以注入,並改變它的狀態,有可能影響計時器回調的行爲。

相關問題