• Keine Ergebnisse gefunden

4. Benutzeragent und Benutzer

4.2 Behandlung des Benutzers

4.2.1 Rollback nach der Bearbeitung

In diesem Szenario erhält der Benutzeragent (User Agent) von der ConTract Engine eine Aufgabe zur Abarbeitung durch seinen Benutzer, die er an die Oberfläche das Tasklist Interface -weiterleitet, sobald dieses vom Benutzer gestartet wird. Nach der Bearbeitung wird das Er-gebnis an den Benutzeragenten übermittelt und von diesem an die ConTract Engine weiterge-geben. Für den Benutzer ist die Aufgabe zu diesem Zeitpunkt erfolgreich bearbeitet und abge-schlossen. Nun erfolgt jedoch ein Zurücksetzen der zugehörigen Transaktion.

Aufgabe bearbeiten ConTract

Engine

Benutzer-agent

Tasklist Interface und Benutzer Aufgabe verschicken

Aufgabe weiterleiten

Ergebnis zurückschicken Ergebnis weiterleiten

Zurücksetzen der Transaktion

Meldung an den Benutzer?

an der Transaktion teilnehmende Komponenten

OTS

Abbildung 12: Zurücksetzen einer Transaktion nach der Bearbeitung durch den Benutzer Es gibt nun zwei prinzipielle Ansätze, wie sich das System gegenüber dem Benutzer verhalten kann:

4.2.1.1 Der Benutzer als gewöhnlicher Stepserver

Die einfachste Möglichkeit besteht darin, den Benutzer zu behandeln wie einen gewöhnlichen automatischen Stepserver, das heißt das vom Benutzer erarbeitete Ergebnis wird vom System ohne eine Benachrichtigung weggeworfen. Da die ConTract Engine im Falle des Zurückset-zens einer Transaktion höchstwahrscheinlich nochmals versucht, den Step auszuführen, also dieselbe Transaktion nochmals startet, wird dem Benutzer über kurz oder lang dieselbe Auf-gabe erneut vorgelegt.

Da der Benutzeragent nur aus einem Grunde als Recoverable Server am transaktionalen Pro-tokoll des OTS teilnimmt, nämlich um den Benutzer über den Ausgang der Transaktion zu informieren, würde die Implementierung des Benutzeragenten durch diese Vorgehensweise stark vereinfacht, da durch den Verzicht auf eine Benachrichtigung des Benutzers die Zusam-menarbeit mit dem OTS entfällt.

Ein solches Verhalten des Systems ist dem Benutzer jedoch unter dem Gesichtspunkt der An-wenderfreundlichkeit nicht zumutbar, da unter Umständen von ihm verlangt wird, dieselbe Aufgabe wieder und wieder auszuführen. Auch möchte ein menschlicher Bearbeiter vermutlich erfahren, ob die Transaktion an der er mitgewirkt hat, erfolgreich verlaufen ist oder nicht.

4.2.1.1 Sonderbehandlung des Benutzers

Wir müssen also besonderes Augenmerk auf zwei Aspekte legen: Zum einen soll der Benutzer davor bewahrt werden, nach einem Abbruch der Transaktion dieselbe Aufgabe nochmals bear-beiten zu müssen. Zum anderen ist eine Mitteilung an den Benutzer darüber, was mit dem von ihm erarbeiteten Ergebnis geschehen ist, notwendig.

Aufbewahren alter Arbeitsergebnisse

Um die erste Anforderung zu erfüllen, kann der Benutzeragent die vom Benutzer erarbeiteten Ergebnisse auch nach dem Abbruch der Transaktion aufbewahren. Tritt nun der oben erwähnte Fall ein, daß dieselbe Aufgabe nochmals eintrifft, so kann das vom Benutzer zuvor erbrachte Ergebnis für diesen erneuten Aufruf verwendet werden. Dieser Vorgang könnte soweit auto-matisiert werden, daß der Benutzeragent die Aufgabe gar nicht erst an den Benutzer weiter-reicht, sondern, sobald er erkennt, daß die Aufgaben identisch sind, von sich aus das alte Er-gebnis an die ConTract Engine zurückschickt.

Der flexibelste Ansatz besteht jedoch darin, den Benutzer mit einzubeziehen. Es wäre nämlich denkbar, daß der Benutzer beispielsweise beim ersten Eintreffen der Aufgabe einen Bericht über einen Sachverhalt geschrieben hat, bei dem sich bis zum zweiten Eintreffen der Aufgabe einige Änderungen ergeben haben. Würde jetzt der Benutzeragent automatisch den alten Be-richt zurückschicken, so wäre dieser im günstigsten Fall veraltet, im schlimmsten Fall vielleicht sogar nicht mehr korrekt. Eine Einbeziehung des Benutzers ist folglich erstrebenswert.

Meiner Ansicht nach sollte daher der Benutzer die neu eingetroffene Aufgabe zusammen mit den Ergebnissen der früheren Bearbeitung erhalten. Er kann dann frei die Entscheidung treffen, was problemlos übernommen werden kann und wo er möglicherweise noch Änderungen an-bringen sollte.

Durch diese Vorgehensweise hat der Benutzer die größtmöglichen Freiheiten ohne daß der Benutzeragent auf die Teilnahme am transaktionalen Protokoll verzichten muß. Einerseits bricht der Benutzeragent dadurch, daß er Ergebnisse aufbewahrt, die zu abgebrochenen Trans-aktionen gehören, die Regel, daß jegliche Spur einer solchen Transaktion aus dem System ge-tilgt werden soll; andererseits verbirgt er diese Tatsache vor dem System, so daß er formal allen Anforderungen genügt, die an eine an einer Transaktion teilnehmende Komponente ge-stellt werden.

Die letztendliche Entscheidung, wie mit dem Benutzer umgegangen wird, läßt sich jedoch auf der Ebene des Benutzeragenten nicht treffen, da dieser nur mittelbar über die Benutzungsober-fläche - das Tasklist Interface - mit dem Benutzer kommuniziert. Er sollte also so flexibel kon-zipiert sein, daß er die Entscheidungen, die beim Entwurf der Benutzungsoberfläche getroffen werden, möglichst in keiner Weise einengt.

Aus diesem Grunde ist die Schnittstelle zwischen dem Benutzeragenten und dem Tasklist In-terface sehr allgemein gehalten (siehe Schnittstellen des Benutzeragenten im Anhang). Die Oberfläche kann sich über den Aufruf von

void getTask(

in string taName, out string request,

out string tasklistInfo,

out APRICOTS_Definitions::FileSequence params) raises (AgentError);

eine beliebige Aufgabe vom Benutzeragenten geben lassen. Dabei ist es unerheblich, ob es sich um eine vom Benutzer noch nicht begonnene, eine gerade in Bearbeitung befindliche oder eine schon abgeschlossene Aufgabe handelt. Es ist also - wenn die Oberfläche ein solches Vorgehen unterstützt - möglich, über diesen Aufruf eine alte, schon längst fertig bearbeitete Aufgabe, die zu einer abgebrochenen Transaktion gehört, nochmals darzustellen. Der Benutzer kann nun die alten Ergebnisse für die Bearbeitung der neuen, aber identischen, Aufgabe verwenden. Diese Vorgehensweise ist jedoch nicht zwingend: besteht von Seiten der Benutzungsoberfläche der Wunsch, die alten Ergebnisse unberücksichtigt zu lassen, so ist dies problemlos möglich.

Der Benutzeragent bewahrt also auch Aufgaben und ihre Ergebnisse auf, wenn die zugehöri-gen Transaktionen schon längst entweder erfolgreich beendet oder aber zurückgesetzt worden sind. Hier stellt sich zwangsläufig die Frage, wie lange diese Aufbewahrung erfolgen soll.

Eine Möglichkeit wäre das automatische Löschen nach einem bestimmten Zeitlimit. Die Schwierigkeit hierbei ist jedoch die Wahl der idealen Aufbewahrungszeit. Wird diese zu kurz gewählt, dann werden Aufgaben gelöscht, die der Benutzer vielleicht zur Bearbeitung eines neuen Auftrages benötigt; wählt man sie zu lang, dann verliert der Benutzer wegen der großen Anzahl leicht den Überblick über seine schon beendeten Aufgaben.

Die bessere Lösung stellt daher auch hier wieder die Einbeziehung des Benutzers dar. Der Be-nutzeragent bietet über die Schnittstelle

void deleteTask(in string taName) raises (AgentError);

die Möglichkeit, nicht mehr benötigte Aufgaben durch den Benutzer löschen zu lassen. Auch hier wiederum entscheidet jedoch letztendlich das Tasklist Interface über die Beteiligung des Benutzers: Ist diese nicht gewünscht, so kann die Oberfläche diese Schnittstelle automatisch aufrufen und dadurch Aufgaben ohne Zutun des Benutzers löschen.

Die Frage, wie die Benutzungsoberfläche letztendlich mit den Möglichkeiten, die der Benut-zeragent bietet, umgeht, wird in der Ausarbeitung zum Tasklist Interface, das parallel zu dieser Studienarbeit entwickelt wird, behandelt.

Benachrichtigung des Benutzers

Für die Motivation des Benutzers ist es wichtig, daß er nach der Abarbeitung einer Aufgabe eine Rückmeldung erhält, was mit seinen Arbeitsergebnissen geschehen ist. Er sollte also, falls die Transaktion erfolgreich beendet wird (Commit), eine Meldung von der Art „Die Ergebnisse der Aufgabe XYZ wurden erfolgreich bearbeitet!“ erhalten; im Falle eines Zurücksetzens der Transaktion (Abort) sollte er auch dies erfahren: „Die Ergebnisse der Aufgabe XYZ konnten nicht weiterbearbeitet werden!“.

Wird die oben erwähnte Alternative gewählt, daß im Falle eines Transaktionsabbruchs das Er-gebnis aufbewahrt und bei einem erneuten Eintreffen der Aufgabe automatisch und ohne Zutun des Benutzers verwendet wird, so muß die Meldung eines negativen Ausgangs zunächst zu-rückgehalten werden. Erst wenn feststeht, daß alle Versuche, diese Transaktion auszuführen, gescheitert sind, darf der Benutzer davon in Kenntnis gesetzt werden.

Um den Benutzer vom Ausgang einer Transaktion benachrichtigen zu können, ist es unerläß-lich, daß der Benutzeragent am Commit-Protokoll des OTS (Object Transaction Service) teil-nimmt. Nur auf diese Art und Weise kann er erfahren, ob eine Transaktion erfolgreich beendet wird (Commit) oder nicht (Abort). Er registriert zu diesem Zwecke beim Transaction Service für jede Aufgabe eine Resource, die über die beiden Schnittstellen

void rollback ()

raises ( HeuristicCommit, HeuristicMixed, HeuristicHazard );

void commit ()

raises ( NotPrepared, HeuristicRollback, HeuristicMixed, HeuristicHazard );

im Rollback- oder im Commit-Fall der Transaktion beziehungsweise über die Schnittstellen void commit_subtransaction ( in Coordinator parent );

void rollback_subtransaction ();

beim Rücksetzen oder erfolgreichen Ende der Subtransaktion vom OTS einen entsprechenden Aufruf erhalten (siehe auch [OTS94]).

Diese Informationen gibt der Benutzeragent dann über die folgenden Schnittstellen an das Tasklist Interface weiter:

string getAbortedTask() raises (AgentError);

string getCommittedTask() raises (AgentError);

Natürlich liegt es auch hier wiederum im Ermessen der Oberfläche, was dem Benutzer in den beiden Fällen angezeigt wird und ob die Aufgaben mittels der oben erwähnten deleteTask()-Schnittstelle nach dem Anzeigen gelöscht werden sollen oder nicht.

Könnte man auf die Benachrichtigung des Benutzers über den Ausgang einer Transaktion ver-zichten, so bräuchte der Benutzeragent nicht am transaktionalen Protokoll teilzunehmen. Eine Aufgabe wäre dann für diesen in dem Moment erledigt, wenn die Ergebnisse an die ConTract Engine weitergeliefert werden.