2011-03-28 27 views
4

我正在使用JBoss AS 6編寫Java EE應用程序,並且我有一個資源需要對給定參數的方法進行獨佔訪問(某些第三方軟件的接口)。目前我很淘氣(自specification prohibits it以來)並使用java.util.concurrent.ReentrantLock來處理鎖定。分佈式鎖定和Java EE

現在我正在將多個JBoss應用程序服務器集中在一起,因此我需要一個可在集羣中的不同節點上工作的解決方案。我認爲我至少有以下選擇。

  1. 共享高速緩存(Infinispan的)
  2. JGroups
  3. 基於文件系統的鎖定(可能不好,但我們依靠一個共享文件系統上是這樣)
  4. 數據庫
  5. Singleton EJB的?

理想情況下,我正在尋找一個高層次的API,所以我可以寫EJB方法這樣

public class MyEJBBean { 

    private SharedLock lock; 

    public void doSomethingWithSharedResource(String s) { 
     lock.lock(); // blocks until shared resource is not used by anyone else 
     try { 
      // Use shared resource 
     } 
     finally { 
      lock.unlock(); 
     } 
    } 

我已經錯過任何選項?有沒有人有這種鎖定機制的經驗,他們可以分享?

回答

2

理想情況下,我會建議將第三方軟件包裝到僅在單個實例上運行的單獨應用程序中。通過這種方式,您可以使用EJB單例處理鎖定(我相信@Singleton在您的場景中不會幫助您)並使用遠程EJB/WS對其進行公開。看起來這個軟件有點討厭(單線程?),所以擁有更多用戶友好的EJB接口將是一個額外的好處。

想一想 - 如果一次只能訪問整個系統一次,那麼爲什麼還要分發它呢?總是最多隻能有一個實例可以使用。

如果你想堅持均勻分佈式系統(這通常不是一個壞主意),我會建議使用SELECT FOR UPDATE來鎖定數據庫。我從來沒有嘗試過,但我認爲在使用你的庫之前發佈這樣的SQL(獲得一個鎖)並讓EJB容器事後提交事務(有效地釋放鎖)將會起作用。

+3

我們之前已經完成了數據庫鎖定技術。如果你有一個支持集羣的數據庫實例,那麼這是一個完全有效的,便宜的鎖定方式。另一個想法是將第三方服務例程放在JMS隊列的另一端。請求會被髮布到隊列中,服務將對其執行操作,然後通過附加到消息的臨時隊列(或其他)將結果發回。很明顯,仍然存在鎖定,但它位於JMS服務器中,而不再是應用程序中的第一類概念。 – 2011-03-28 17:29:27

+0

+1,JMS與單個消費者似乎是最JEE的方式,我喜歡它。 – 2011-03-28 17:31:47

+0

這比它稍微複雜一些。該API有一個方法foo(String s) - 該方法不能同時用相同的s調用兩次。聽起來像是一個很好的建議,所以明天我上班時我會玩一玩。 – 2011-03-28 18:04:23