2016-11-22 3 views
0

Ich habe in Activiti einen Prozess ausgeführt, der nur aus Serviceaufgaben besteht. Der Prozess läuft lange und in einigen Fällen möchte ich ihn auf halbem Wege beenden. Prozess gestartet wird mitactiviti - Laufende Prozessinstanz beenden

ProcessInstance pi = runtimeService.startProcessInstanceById(
       processDefinitionId, executionParameters); 

Vom activiti forum können Prozesse durch

Aufruf beendet
void deleteProcessInstance(String processInstanceId, String deleteReason); 

auf runtimeService.

Das Problem ist, dass die startProcessInstanceById Methode nur zurückkehrt, nachdem die Ausführung abgeschlossen ist. Also bekomme ich die processInstance nicht, wenn der Prozess beendet ist.

Allerdings habe ich den Code debuggen und ich bin in der Lage, die processInstanceId in der Implementierung von JavaDeleate#execute() Methode zu finden.

Jetzt, wenn ich runtimeService.deleteProcessInstance(processInstanceId, deleteReason) Methode aus einem anderen Thread aufrufen, bekomme ich ActivitiObjectNotFoundException, dass die angegebene processInstanceId existiert nicht. Wenn die processInstance ausgeführt wird, gibt das Aufrufen von runtimeService.createProcessInstanceQuery().list() außerdem eine leere Liste zurück, obwohl der Prozess ausgeführt wird.

Antwort

2
void deleteProcessInstance(String processInstanceId, String deleteReason); 

verwendet processInstanceId, die nur in dem Fall vorhanden ist, wenn die Transaktion festgeschrieben ist. (Siehe transactions in activiti) ich nicht prüfen, ob es möglich ist, zur Zeit löschen Prozessinstanz ausgeführt wird, aber ich würde eine Art von Ausnahme erwartet dort (laufende Prozessinstanz gelöscht Ausführung Referenzierung)

In Ihrem Fall würde ich Flagge hinzufügen um anzuzeigen, ob der Prozess beendet werden muss. Diese Flagge kann z.B. Listener während der Prozessinstanzausführung. Wenn Sie Ihr Prozessmodell nicht unordentlich machen möchten, können Sie den Listener automatisch zum Modell hinzufügen (siehe Hooking into process parsing).

+0

Martin hat hier die richtige Antwort. Verwenden Sie einen Parse-Handler, um jedem Service-Task automatisch einen Listener hinzuzufügen, der die Instanz auf der Aktivitätsgrenze beendet (entweder beim Beenden oder beim Erstellen von Ereignissen). Sie werden nicht in der Lage sein, die REST-API oder Standard-Java-Prozessinstanz zu verwenden, um Aufrufe zu beenden oder zu löschen, da Sie niemals mit Ihrem "Durchgehenden Prozess" in die Datenbank gelangen. –

1

Der Prozess wird an die Datenbank übergeben, sobald er bei jeder Ausführung den asynchronen Punkt erreicht. Andere Threads sehen Ihren Prozess vor dieser Zeit nicht.

Der einfachste Weg, um Ihren Prozess zu enthüllen, besteht darin, den ersten Schritt asynchron zu machen. Auf diese Weise erhält der aufrufende Thread die Kontrolle zurück, sobald der Prozess erstellt wird. In diesem Fall wird der Jobexecutor die Arbeit an dem Prozess von einem asynchronen Punkt aus fortsetzen (der Kontext der Webanfrage geht verloren. Wenn Sie einen brauchen, müssen Sie ihn übergeben, um ihn zum Beispiel als Prozessvariablen zu verarbeiten). Sie müssen in diesem Fall Abfragen für Ergebnisse durchführen oder andere Synchronisierungsmechaniken verwenden, wenn Sie das Prozessergebnis sofort zurückgeben möchten.

Ich bin mir nicht sicher in diesem Fall deleteProcess wird eigentlich immer Prozess löschen, gibt es die Möglichkeit, db Sperren Ausnahmen zu begegnen. Aber Sie können die gesamte Arbeit im Subprozess mit dem breaking interrupting signalCatchingEvent erledigen, das Ihren Prozess wahrscheinlich sofort abbrechen wird.

Verwandte Themen