2016-05-13 8 views
0

Ich arbeite in einem LR 6.2 CE GA4 Clustered Umgebung. Die 2 Knoten teilen sich die gleiche DB mit dem gemeinsam genutzten Cache über die Portal-Ext-Cluster-Konfiguration.Umgang mit Nebenläufigkeit in Liferay Cluster

Ich habe einen Scheduler Aufruf der Methode processMe() alle 15 Minuten, die auch von einem Benutzer beim Klicken auf eine Seite aufgerufen werden kann.

Meine Anforderung ist, den gleichzeitigen Aufruf dieser Methode zu beschränken. Ich verstehe, dass synchronisierte Blöcke aufgrund der verschiedenen JVMs nicht arbeiten werden.

Gibt es etwas, was ich OOTB aus Liferay wiederverwenden kann? Kann ich etwas aus der JGroups Unicast/Multicast-Kommunikation wiederverwenden?

Haben Sie noch weitere Vorschläge?

in liferay Forum Verfasst am:https://web.liferay.com/community/forums/-/message_boards/message/74168121

Danke,

Siby Mathew

+0

Wo würden Sie die Antwort bekommen? Hier? Oder auf Liferays Forum? Anderswo? Bitte lies http://meta.stackexchange.com/questions/141823/why-is-cross-posting-wrong-on--external-site und aktualisiere/verlinke/lösche entsprechend. –

+0

Ich habe einen Link zu meinem Beitrag in liveray hinzugefügt Forum – simplysiby

Antwort

0

ich die Lösung nach der Methode bezieht gefunden haben: com.liferay.portal.kernel.backgroundtask.SerialBackgroundTaskExecutor .acquireLock()

Hier ist der Code:

@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; 
} 

Die große Veränderung in meinem Code war

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

Grundsätzlich selbst wenn zwei Threads in der Lage, das Schloss() -Methode zu überprüfen aufzurufen (was ich Tests durch Brennen zwei Disponenten gleichzeitig war), nur eine Der Thread wird erfolgreich beim Erstellen des neuen Objekts und der andere wird nur das vorhandene Sperrobjekt abrufen.

Daher lock.isNew() sollte den Thread finden, der die echte Sperre hält.

Danke,

Siby Mathew