2016-05-13 40 views
0

我正在LR 6.2 CE GA4中工作羣集環境。 2個節點通過portal-ext集羣配置共享具有共享緩存的相同數據庫。處理Liferay Cluster中的併發問題

我有一個調度程序調用方法processMe()每隔15分鐘,也可以由用戶在點擊頁面時調用。

我的要求是限制對此方法的併發調用。 據我所知,同步塊不會工作,由於不同的JVM。

有沒有什麼可以在Liferay內重用OOTB的? 我可以重用JGroups單播/多播通信中的某些內容嗎?

其他建議?

發表在Liferay的論壇:https://web.liferay.com/community/forums/-/message_boards/message/74168121

感謝,

西比馬修

+0

你想在哪裏得到的答案?這裏?或者在Liferay的論壇上?別處?請閱讀http://meta.stackexchange.com/questions/141823/why-is-cross-posting-wrong-on-an-external-site並相應地更新/鏈接/刪除 –

+0

我在liferay中添加了一個鏈接到我的帖子論壇 – simplysiby

回答

0

我已經找到了解決方案參考方法之後:com.liferay.portal.kernel.backgroundtask.SerialBackgroundTaskExecutor .acquireLock()

這裏是代碼:

@Override 
    public BackgroundTaskResult execute(BackgroundTask backgroundTask) 
     throws Exception { 

    Lock lock = null; 

    String owner = 
     backgroundTask.getName() + StringPool.POUND + 
      backgroundTask.getBackgroundTaskId(); 

    try { 
     if (isSerial()) { 
      lock = acquireLock(backgroundTask, owner); 
     } 

     BackgroundTaskExecutor backgroundTaskExecutor = 
      getBackgroundTaskExecutor(); 

     return backgroundTaskExecutor.execute(backgroundTask); 
    } 
    finally { 
     if (lock != null) { 
      LockLocalServiceUtil.unlock(
       BackgroundTaskExecutor.class.getName(), 
       backgroundTask.getTaskExecutorClassName(), owner); 
     } 
    } 
} 

protected Lock acquireLock(BackgroundTask backgroundTask, String owner) 
     throws DuplicateLockException { 

    Lock lock = null; 

    while (true) { 
     try { 
      lock = LockLocalServiceUtil.lock(
       BackgroundTaskExecutor.class.getName(), 
       backgroundTask.getTaskExecutorClassName(), owner); 

      break; 
     } 
     catch (SystemException se) { 
      if (_log.isDebugEnabled()) { 
       _log.debug("Unable to acquire acquiring lock", se); 
      } 

      try { 
       Thread.sleep(50); 
      } 
      catch (InterruptedException ie) { 
      } 
     } 
    } 

    if (!lock.isNew()) { 
     throw new DuplicateLockException(lock); 
    } 

    return lock; 
} 

在我的代碼的主要變化是檢查

if (!lock.isNew()) { 
throw new DuplicateLockException(lock); 
} 

基本上即使兩個線程都能夠(通過同時發射兩個調度這點我是測試)來調用lock()方法,只有一個的線程將成功創建新的對象,另一個將只是獲取現有的鎖定對象。

因此lock.isNew()應該找到持有真正鎖的線程。

感謝,

西比馬修