Frank_HLP
Returning Observer

Lock-Mechanismus für Aufträge

Hallo Community,

ich habe einen Workflow entwickelt in dem ein Modul einen Auftrag zum Deployen ausführt. Um zu vermeiden, dass mehrere Benutzer den Auftrag gleichzeitig ausführen, hatte ich zunächst einen Service entwickelt, der einen Lock aus dem JDK verwendet. Diese hat allerdings nicht funktioniert, da trotz Kapselung als statisches Objekt per Singelten für jeden Zugriff ein neues Objekt erzeugt wurde.

Als Workaroud habe ich dann den lock des ScheduleEntry verwendet und so eine Warteschleife entworfen. Das hatte auch prima funktioniert, nur ist es leider so, dass nur ein Administator den ScheduleEntry locken kann. Da normale Editoren den Workflow ebenso ausführen sollen können, ist diese Lösung ein schlecht. Hat jemand einen besseren Vorschlag, wie ich den Auftrag sperren und die Warteliste anpassen kann? Gibt es einen System weiten Lock-Mechanismus den ich dazu verwenden kann?

Aktuell sieht mein Code in etwa so aus:

public void run() {

  List<ScheduleEntry> allScheduleEntries;

  ScheduleEntry scheduleEntry = null;

  try {

    allScheduleEntries = scheduleStorage.getScheduleEntries(proj);

  } catch (Exception e) {

    e.printStackTrace();

    return;

  }

  for (ScheduleEntry entry : allScheduleEntries) {

    if (entry.getName().equalsIgnoreCase(schedulename)) {

      scheduleEntry = entry;

      break;

    }

  }

  if (scheduleEntry == null) {

    warn("The ScheduleEntry '" + schedulename + "' does not exist!", this);

    return;

  }

  long extitTime = System.currentTimeMillis() + TimeUnit.MILLISECONDS.convert(1, TimeUnit.HOURS);

  while (!scheduleEntry.isLocked() && System.currentTimeMillis() < extitTime) {

    try {

      scheduleEntry.lock();

    } catch (Exception e) {

      Thread.sleep(1000);

    }

  }

   ...

     scheduleEntry.unLock();

}

Gruß und Dank

Frank

0 Kudos
5 Replies
Peter_Jodeleit
Crownpeak employee

Reichen dir die Einstellungen im Auftrag nicht, welche steuern, ob dieser parallel ausgeführt werden darf?

Peter
0 Kudos

Leider nicht, da ich den Auftrag im Workflow konfiguriere, möchte ich diesen auch sperren. Die Anforderung war so, dass wartende Aufträge zusammengefasst werden, um die Wartezeit zu verringern. Deshalb reichen die Einstellungen im Auftrag nicht aus. Generell würde es mich auch interessieren, ob es einen serverseitigen Lock gibt, den ich, wie in meiner Frage beschrieben, im Service verwenden kann. Diesen würde ich dann zum gegenseitigen Ausschluss gemeinsamer Ressourcen verwenden.

Gruß

Frank

0 Kudos

Nein, so etwas stellen wir nicht als Service bereit.

Der Weg der Wahl wäre, einen Service zu implementieren, welcher die passende fachliche Logik bereitstellt.

Peter
0 Kudos

Richtig! Genau das war auch mein erster Versuch. Leider hatte dies nicht funktioniert, da der Service (so wie es sich für mich dargestellt hat) jede Session, die auf den Service zugreift, in einer eigene JVM ausführt. Ansonsten kann ich mir nicht erklären, warum Objekte mit den Attributen final und static im Service unterschiedliche Werte annehmen können. Somit ist es nicht möglich bespielsweise die Klasse ReentrantLock einzusetzen.

0 Kudos

Nein, das geht nicht - und wenn man bedenkt, das die Methoden auch verteilt funktionieren müssen, würde das auch keinen Sinn machen. Ich dachte an Service-Methoden wie "lock()" und "unlock()" (eventuell auch jeweils mit Parameter, wenn man mehr als einen globalen Lock haben will).

Peter
0 Kudos