• Keine Ergebnisse gefunden

Verteilte Transaktionen und

N/A
N/A
Protected

Academic year: 2022

Aktie "Verteilte Transaktionen und "

Copied!
98
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Verteilte Systeme

Verteilte Transaktionen und

Nebenläufigkeitskontrolle

(2)

Transaktionen

(3)

Motivation

‹ Wir haben im letzten Kapitel bereits das Konzept des gegenseitigen Ausschlusses bei Zugriff auf kritische Abschnitte betrachtet.

‹ Ziel: eine bestimmte Ressource soll nur von einem Client zur selben Zeit benutzt werden

‹ Ganz generell haben Transaktionen dasselbe Ziel: Schutz von Ressourcen vor gleichzeitigem Zugriff.

‹ Transaktionen gehen jedoch noch wesentlich weiter:

Automatisches Erzwingen der Konsistenzwahrung

– Es ist möglich, auf mehrere Ressourcen in einer einzigen atomaren Operation zuzugreifen, d.h. Umgang mit verschiedenen kritischen Abschnitten

– Diverse Arten von Fehler können abgefangen werden, so daß Prozesse in den Zustand vor Beginn der Ausführung einer Transaktion zurückgesetzt

(4)

Beispiel

‹

Wir wollen die in diesem Kapitel vermittelten Konzepte anhand eines durchgängigen Beispiel erläutern.

‹

Es gibt zwei Arten von Ressourcen:

Account-Objekte (Konto-Objekt), die Abbuchungen und Einzahlungen gestatten sowie Abfragen und Änderungen des Kontostands

Branch-Objekte (Bankfiliale-Objekt), die eine Filiale

repräsentieren und es gestatten, Konten zu erzeugen,

Konten zu suchen und den Gesamtstand aller Konten in

dieser Filiale abzufragen.

(5)

Beispiel: Methoden

Methoden des Branch-Objekts

‹ create(name) -> account Erzeugt neues Konto name

‹ lookUp(name) -> account Gibt Verweis auf Konto name zurück

‹ branchTotal() -> amount Gibt Gesamtsumme aller Konten zurück

Methoden des Account-Objekts

‹ deposit(amount)

Zahlt amount (Betrag) auf Konto ein

‹ withdraw(amount)

Hebt amount von Konto ab

‹ getBalance() -> amount Gibt Kontostand zurück

‹ setBalance(amount)

Setzt Kontostand auf amount

(6)

Einfache Synchronisation

(ohne Transaktion)

‹

Im Account-Objekt müssen die Operationen deposit() und withdraw() atomar ausgeführt werden, d.h. sie dürfen in der Ausführung nicht unterbrochen werden.

‹

In Java läßt sich das auf einfache Weise unter Verwendung des Schlüsselwortes synchronized erreichen:

public synchronized void deposit(...);

‹

Ergebnis: wenn mehrere Threads gleichzeitig dieselbe bzw.

eine andere synchronisierte Methode dieses Objekts

benutzen wollen, wird nur ein Thread zugelassen; die

anderen werden blockiert.

(7)

Fehlermodell für Transaktionen

‹

B.W. Lampson führte 1981 ein Fehlermodell ein, das heute als Grundlage aller Transaktionsalgorithmen verwendet wird.

Ein Algorithmus muß demnach folgende (vorhersehbare) Fehler behandeln können:

Fehler beim Schreibzugriff auf permanenten Speicher – Server-Absturz

– Beliebige Verzögerungen bei der Nachrichtenübertragung

‹

Im Katastrophenfall keine Aussage über die Folgen.

– Schreiben in falschen Block ist Katastrophe

– Gefälschte Nachrichten sowie nicht erkannte fehlerhafte

(8)

Transaktionen

‹

Transaktionen bestehen aus einer Folge von Operationen (Anfragen an Server), für die bestimmte Eigenschaften gelten – die ACID-Eigenschaften.

‹

Beispiel für eine Transaktion in der Bankanwendung:

– eine Kunde will verschiedene Operationen auf drei Konten a, b und c ausführen.

– Die Operationen sollen ohne Unterbrechung ausgeführt werden.

Transaction T:

a.withdraw(100);

b.deposit(100);

c.withdraw(200);

b.deposit(200);

(9)

Transaktionen: ACID-Eigenschaft

‹

ACID ist ein von T. Härder und A. Reuter 1983 vorgeschlagenes Acronym.

‹

Bedeutung:

– – Atomicity: Alles-oder-Nichts A Eigenschaft: Die Transaktion wird entweder vollständig ausgeführt oder hinterläßt keine Wirkung.

– – Consistency: eine Transaktion überführt das System von C einem konsistenten Zustand in einen konsistenten Zustand.

– – Isolation: jede Transaktion muß von der Ausführung anderer I Transaktionen unabhängig bleiben (Serialisierbarkeit).

– – Durability: Die Änderungen einer beendeten und bestätigten D

(10)

ACID (1): Atomarität und Dauerhaftigkeit

‹

Atomicity und Durability

– ist gefährdet durch eine fehlerhafte Umgebung und

– wird erreicht durch die Verwendung wiederherstellbarer Objekte.

‹

Wenn ein Server-Prozeß während der Abarbeitung einer Transaktion abstürzt und dann ein neuer Prozeß gestartet wird, dann muß dieser den alten Zustand der Objekte wieder laden können.

‹

Wenn die Transaktion abgeschlossen ist, muß das Objekt den neuen Zustand repräsentieren und abgespeichert

werden.

(11)

Implementierung

‹

Für jede Transaktion gibt es einen Koordinator (Transaction Monitor), der den Ablauf steuert.

‹

Verwendung:

– Der Client startet eine Transaktion, woraufhin der Koordinator eine Transaktions-ID (TID) allokiert und zurückgibt.

– Dann werden die Operationen ausgeführt.

– Am Ende ruft der Client ein

closeTransaction()

auf,

woraufhin der Koordinator alle Objekte speichert und eine positive oder negative Abschlussmeldung liefert.

– Der Client kann auch von sich aus die Transaktion

(12)

Implementierung: Methoden

‹

openTransaction() -> trans;

startet eine neue Transaktion und gibt die

eindeutige TID

trans

zurück. Diese ID wird in den anderen Operationen der Transaktion verwendet.

‹

closeTransaction(trans) -> (commit, abort);

beendet eine Transaktion: der Rückgabewert

commit

zeigt an, daß die Transaktion festgeschrieben wird; der Rückgabewert

abort

zeigt an, daß sie abgebrochen wurde.

‹

abortTransaction(trans);

bricht die Transaktion

trans

ab.

(13)

Beispiel: Java TransactionManager

‹ Findet sich in javax.transaction.

‹ Ausschnitt aus der Schnittstelle:

void resume(Transaction tobj)

Resume the transaction context association of the calling thread with the transaction represented by the supplied Transaction object.

void suspend()

Suspend the transaction currently associated with the calling thread and return a Transaction object that represents the transaction context being suspended.

Transaction rollback()

Roll back the transaction associated with the current thread void getTransaction()

Get the transaction object that represents the transaction context of the calling thread

Transaction commit()

Complete the transaction associated with the current thread

(14)

Implementierung: Transaktions-ID

‹

Bei jeder Operation, die ein Client für eine Transaktion durchführt, muß er die Transaktions-ID (TID) angeben.

‹

Mögliche Implementierungen:

– Angabe als zusätzlicher Parameter in den Operationen, z.B.

deposit(trans, amount)

– Bei Verwendung von Middleware wird die TID

üblicherweise implizit bei allen entfernten Aufrufen

angegeben, z.B. beim CORBA CORBA Transaction Transaction Service. Der Service Anwendungsprogrammierer muß sich darum nicht

kümmern.

(15)

Beispiel: Transaktionshistorie

Successful Aborted by client Aborted by server

openTransaction openTransaction openTransaction

operation operation operation

operation operation operation

server aborts transaction

operation operation operation ERROR

reported to client closeTransaction abortTransaction

(16)

Geschachtelte Transaktionen

‹ Geschachtelte Transaktionen erweitern das bisherige (flache)

Transaktionsmodell, indem sie gestatten, daß Transaktionen aus anderen Transaktionen zusammengesetzt sind.

‹ Die Transaktion auf der höchsten Ebene wird als toplevel transaction bezeichnet, die anderen als subtransactions.

‹ Zusätzliche Nebenläufigkeit:

Subtransactions auf der selben Hierarchieebene können nebenläufig ausgeführt werden

– Bankenbeispiel: die Operation branchTotal() muß für sämtliche Konten die Methode getBalance() aufrufen. Man könnte jeden dieser Aufrufe als Untertransaktion starten

‹ Unabhängiges Commit oder Abort:

– Dadurch werden Transaktionen potentiell robuster (hängt von der Anwendung ab)

– Die Elterntransaktion muß jeweils entscheiden, welche Folge ein Abort der Untertransaktion haben soll.

(17)

Geschachtelte Transaktion: Regeln

1. 1. Eine Transaktion darf nur abgeschlossen werden, wenn ihre Untertransaktionen abgeschlossen sind.

2. Wenn 2. eine Untertransaktion abschließt, entscheidet sie

unabhängig, entweder provisorisch festzuschreiben (commited) oder endgültig abzubrechen.

3. Wenn 3. eine Elterntransaktion abbricht, werden auch alle Subtransaktionen abgebrochen.

4. Wenn 4. eine Subtransaktion abbricht, entscheidet die Elterntransaktion, was weiter geschieht.

5. Wenn 5. eine Elterntransaktion festgeschrieben ist, dann können

alle provisorisch festgeschriebenen Untertransaktionen ebenfalls

(18)

Transaktionen: ACID-Eigenschaft

‹

ACID ist ein von T. Härder und A. Reuter 1983 vorgeschlagenes Acronym.

‹

Bedeutung:

– – Atomicity: Alles-oder-Nichts A Eigenschaft: Die Transaktion wird entweder vollständig ausgeführt oder hinterläßt keine Wirkung.

– – Consistency: eine Transaktion überführt das System von C einem konsistenten Zustand in einen konsistenten Zustand.

– – Isolation: jede Transaktion muß von der Ausführung anderer I Transaktionen unabhängig bleiben (Serialisierbarkeit).

– – Durability: Die Änderungen einer beendeten und bestätigten D

(committed) Transaktion können weder verloren gehen noch

rückgängig gemacht werden.

(19)

ACID (2): Isolierung und Konsitenz

‹

Die Operationen aller Transaktionen müssen so synchronisiert werden, daß Isolation und Consistency erreicht werden.

‹

Die beiden Eigenschaften sind gefährdet durch Interferenzen nebenläufiger Transaktionen.

‹

Einfachste Variante: Serielle Ausführung der Transaktionen

‹

Ist nicht wünschenswert, da die Performance des Servers sehr schlecht wäre und mögliche nebenläufige Ausführungen von Transaktionen würden nicht berücksichtigt.

‹

Zur Maximierung der Leistung wird deshalb versucht, die

Nebenläufigkeit zu maximieren: Zwei Transaktionen dürfen

nebenläufig ausgeführt werden, wenn diese Ausführung

(20)

Nebenläufigkeitskontrolle

(21)

Nebenläufigkeitskontrolle

‹

Nebenläufigkeitskontrolle (Concurrency Control) ist die wichtigste Aufgabe des Transaktionsmanagers, um die Nebenläufigkeit maximieren zu können.

‹

Aufgabe: finde möglichst nebenläufige Ablaufpläne für Transaktionen, ohne das serielle Äquivalentskriterium zu verletzen.

‹

Es geht also im wesentlichen darum, miteinander in Konflikt

stehende Operationen korrekt einzuplanen.

(22)

Interferenzen nebenläufiger Transaktionen

Transaction T:

balance = b.getBalance();

b.setBalance(balance*1.1);

a.withdraw(balance/10)

Transaction U:

balance = b.getBalance();

b.setBalance(balance*1.1);

c.withdraw(balance/10);

balance = b.getBalance();

b.setBalance(balance*1.1);

a.withdraw(balance/10);

$200

balance = b.getBalance();

b.setBalance(balance*1.1);

c.withdraw(balance/10);

$200

$220

$220

$20 $20

Problem der verlorenen Updates

Problem der verlorenen Updates

(23)

Korrekte Interferenz

Transaction T:

balance = b.getBalance();

b.setBalance(balance*1.1);

a.withdraw(balance/10)

Transaction U:

balance = b.getBalance();

b.setBalance(balance*1.1);

c.withdraw(balance/10);

balance = b.getBalance();

b.setBalance(balance*1.1);

a.withdraw(balance/10);

$200

balance = b.getBalance();

b.setBalance(balance*1.1);

c.withdraw(balance/10);

$220

$242

$220

$20 $22

(24)

Interferenzen nebenläufiger Transaktionen

Problem der

inkonsistenten Abrufe Problem der

inkonsistenten Abrufe

$200 == a.getBalance()

$200 == b.getBalance() Transaction V:

a.withdraw(100) b.deposit(100) a.withdraw(100);

b.deposit(100)

Transaction W:

aBranch.branchTotal()

total = a.getBalance()

total = total+b.getBalance() total = total+c.getBalance()

$100

$300

$100

$300

(25)

Korrekte Interferenz

$200 == a.getBalance()

$200 == b.getBalance() Transaction V:

a.withdraw(100) b.deposit(100) a.withdraw(100);

b.deposit(100)

Transaction W:

aBranch.branchTotal()

total = a.getBalance()

total = total+b.getBalance() total = total+c.getBalance()

$100

$400

$100

$300

(26)

Wiederherstellung nach Abbrüchen

Vorzeitiges Schreiben Vorzeitiges Schreiben Dirty Read

Dirty Read Transaction T:

balance = a.getBalance();

a.setBalance(balance +10);

Transaction U:

balance = a.getBalance();

a.setBalance(balance +20);

balance = a.getBalance();

a.setBalance(balance +10);

abort transaction;

$100

balance = a.getBalance();

a.setBalance(balance +20);

commit transaction;

$110

$130

$110

a.setBalance(105); a.setBalance(110);

a.setBalance(105);

abort/commit transaction;

$105

a.setBalance(110);

commit/abort transaction;

$110 Kaskadenartige Abrüche

Kaskadenartige Abrüche

Nur vorläufiges commit! Nur vorläufiges commit!

(27)

Konflikte zwischen Operationen

‹

Was bedeutet es, wenn zwei Operationen zueinander im Konflikt stehen?

Ö Ihr kombinierter Effekt hängt von der Reihenfolge ab, in der sie ausgeführt werden.

‹

Mit diesem Begriff läßt sich serielle Äquivalenz formaler definieren:

Ö Zwei Transaktionen sind genau dann seriell äquivalent, wenn alle Paare von miteinander in Konflikt stehenden

Operationen der beiden Transaktionen auf allen betroffenen

Objekten in derselben Reihenfolge ausgeführt werden.

(28)

Beispiel: Konfliktregeln für read & write

Operationen unter-

schiedlicher Transaktionen

Konflikt Grund

read read Nein Weil die Wirkung eines Paares von read-Operationen nicht von der Aus- führungsreihenfolge abhängig ist.

read write Ja Weil die Wirkung einer read- und einer write-Operation von der Aus- führungsreihenfolge abhängig ist.

write write Ja Weil die Wirkung eines Paares von write-Operationen von der Ausführ- ungsreihenfolge abhängig ist.

(29)

Beispiel: Serielle Äquivalenz

‹

Gegeben seien zwei Transaktionen wie folgt:

– T: x=read(i); write(i,10); write(j,20);

– U: y=read(j); write(j,30); z=read(i);

‹

Ist der folgende Ablauf seriell äquivalent?

Warum bzw. warum nicht?

Transaction T: Transaction U:

Der Zugriff auf einzelne Objekte ist serialisiert:

•T greift auf i vor U zu

•U greift auf j vor T zu Aber: Nicht äquivalent!

Korrekt wäre zB:

T greift vor U auf i zu und T greift vor U auf j zu

x = read(i) write(i, 10)

write(j, 20)

y = read(j) write(j, 30) z = read(i)

(30)

Beispiel: Serielle Äquivalenz

Wie im Beispiel U vor T

T vor U

Ausgangswerte

x y z i j

- - - * **

* 20 10 10 20

30

* ** * 10 30

20

* ** 10 10 30

20

‹ Beispiel ist nicht seriell Äquivalent:

weder zu „ T vor U“ noch zu „U vor T“

‹ Serielle Äquivalenz entscheidet nicht über „T vor U“ oder „U vor T“: serielle Äquivalenz sorgt dafür, daß eines von beiden im Ergebnis erzielt wird!

(31)

Architektur eines Transaktionssystems

Transaktionen

Transaktionsverwalter (transaction manager)

Planer

(scheduleranager)

Rücksetzer

(recovery manager)

start, end, read, write, abort, commit

Erhaltung und Wiederherstellung der Daten und ihrer Konsistenz, d.h. Rücksetzung von

Transaktionen (Recovery)

Koordination von Transaktionen (Nebenläufigkeitskontrolle/

Concurrency Control) read, write, abort, commit

read, write, lock, release, abort, commit

read, write

(32)

Nebenläufigkeitskontrolle: Algorithmen

‹

Es geht also nun darum, einen Ablaufplan für zueinander in Konflikt stehende Operationen zu finden.

‹

Drei gängige Ansätze:

Sperren (Locking): pessimistische Systeme

optimistsiche Nebenläufigkeitskontrolle (Optimistic concurrency control)

(Auswertung ganze Transaktion)

Zeitstempel-Reihenfolge (Timestamp ordering)

(Auswertung einzelne Operation)

(33)

Sperren

(34)

Sperren

‹

Älteste und am weitesten verbreitete Form der Nebenläufigkeitskontrolle

‹

Einfachste Variante: exklusive Sperren

– Wenn ein Prozeß Zugriff auf eine Ressource (ein

Datenobjekt) benötigt, bittet er den Planer (über den Transaktionsmanager) um eine exklusive Sperre

– Wenn er sie erhalten hat und seine Arbeit anschließend beendet hat, gibt er die Sperre wieder zurück

‹

Aufgabe des Planers: Vergabe der Sperren in einer Weise,

daß nur serielle äquivalente Abläufe entstehen

(35)

Sperren: Beispiel

Transaction T:

balance = b.getBalance();

b.setBalance(balance*1.1);

a.withdraw(balance/10)

Transaction U:

balance = b.getBalance();

b.setBalance(balance*1.1);

c.withdraw(balance/10);

openTransaction

bal = b.getBalance();

b.setBalance(balance*1.1);

a.withdraw(balance/10);

closeTransaction

openTransaction

bal = b.getBalance();

...

b.setBalance(balance*1.1);

c.withdraw(balance/10);

closeTransaction

Operationen Sperren

Wartet auf Sperre

B sperren C sperren Sperren aufheben

Operationen Sperren

B sperren A sperren Sperren aufheben

(36)

2-Phasen-Sperren

‹ Bekannter Algorithmus, von dem bewiesen ist, daß er seriell äquivalente Ablaufpläne erstellt, wenn sich alle Transaktionen daran halten.

‹ Ähnlich wie bei kritischen Abschnitten werden Sperren benutzt, um in Konflikt stehende Operationen (und damit die aufrufende Transaktion) zu verzögern.

‹ Da Lesezugriffe sich gegenseitig nicht stören, werden zwei Sorten von Sperren vorgesehen: Lesesperren und Schreibsperren

‹ Die Menge der Operationen erweitert sich daher um die Sperroperationen:

– Ist eine Lesesperre gesetzt, so können noch weitere Lesesperren gesetzt werden, aber keine Schreibsperre.

– Ist eine Schreibsperre gesetzt, so können keine weitere Sperren zugelassen werden.

– Lesesperren werden auch geteilte Sperren, Schreibsperren auch exklusive Sperren genannt.

(37)

2-Phasen-Sperren: Anforderungen

1. Eine Transaktion muß jedes Datenelement vor dem ersten Zugriff mit einer dem Zugriff entsprechenden Sperre belegen.

2. Kein Datenelement darf mit unverträglichen Sperren belegt werden.

3. Eine Transaktion darf nach der ersten Freigabe einer Sperre keine weitere Sperre setzen.

4. Am Ende der Transaktion müssen alle von ihr gehaltenen Sperren freigegeben sein.

‹ Forderungen 3 und 4 geben dem Sperrprotokoll seinen Namen:

– eine, in der Sperren sukzessive erworben werden und

– eine, in der die Sperren

(38)

Striktes 2-Phasen-Sperren

‹

Das normale Zwei-Phasen-Sperren erzeugt serialisierbare Pläne, jedoch nicht unbedingt rücksetzbare.

‹

Daher zusätzliche Forderung:

5. Alle jemals erworbenen Sperren werden bis

zum Ende der Trans- aktion gehalten.

‹

Dadurch werden

strikte Pläne erzeugt,

die rücksetzbar sind.

(39)

Zwei-Phasen-Sperren: Anmerkungen

‹ Das strikte Zwei-Phasen-Sperren ist das in der Praxis übliche Verfahren.

‹ Die Sperren müssen nicht vom Programmierer gesetzt werden, sondern werden automatisch vom Planer eingefügt und verwaltet.

‹ Das Zwei-Phasen-Sperren kann (mit Ausnahme der konservativen Variante, alle Sperren am Anfang in einer atomaren Operation zu erwerben) zu Verklemmungen (deadlocks) führen.

‹ Was die Einheit der Sperrung ist, hängt vom Einsatzgebiet der

Transaktionen ab: Das Spektrum reicht von einzelnen Werten über Sätze bis hin zu Mengen von Dateien. (Sperrgranularität)

– kleine Dateneinheiten (feine Granularität) ermöglicht hohe

Nebenläufigkeit, bedeutet aber großen Aufwand zur Verwaltung der Sperren

– große Dateneinheiten (grobe Granularität) reduziert die

(40)

Zwei-Phasen-Sperren: Deadlock

Transaktion T Transaktion U

Operationen Sperren Operationen Sperren

a.deposit(100); Schreibsperre für a

b.deposit(200) b.withdraw(100)

a.withdraw(200);

Wartet auf die Sperre, die U für b hält

Schreibsperre für b

Wartet auf die Sperre, die T für a hält

b a

wartet auf gehalten von

T U

gehalten von

wartet auf

(41)

Deadlock

‹

Ein Deadlock (Verklemmung) ist ein Zustand, in dem jedes Mitglied einer Gruppe von Transaktionen darauf wartet, daß ein anderes Mitglied eine Sperre freigibt.

‹

Je feiner die Granularität bei der Nebenläufigkeitskontrolle ist, desto geringer ist die Gefahr von Deadlocks.

‹

Frage: kann man Deadlocks erkennen bzw. verhindern?

Transaktionen Wartebeziehung

U

Warte-Graph

T

Warte-Graph

(42)

Lösung 1: Ausschließen (Prevention)

‹ Einfache Lösung 1.1: Erwerbe am Anfang der Transaktion die Sperren für alle benötigten Objekte (konservatives Zwei-Phasen-Sperren)

– Erwerb der Sperren muss als atomare Aktion durchgeführt werden – Verhindert Deadlocks, ist aber zu restriktiv

– Außerdem kann es z.B. bei interaktiven Transaktionen sein, daß am Anfang nicht bekannt ist, welche Objekte benötigt werden.

– Eher selten verwendete Lösung

‹ Einfache Lösung 1.2: (vordefinierte) Ordnung auf Sperren (bzw.

Objekten); Anfordern der Sperren in dieser Reihenfolge – Vorzeitiges Sperren

 falls ein Objekt erst später bearbeitet wird, dessen Sperre aber vorher in der Ordnung liegt

 falls nicht bekannt ist, welche Objekte benötigt werden – reduzierte Nebenläufigkeit

(43)

Lösung 1: Ausschließen (Prevention)

Ordnung für Sperren: a vor b

Transaktion T Transaktion U

Operationen Sperren Operationen Sperren

a.deposit(100); Schreibsperre für a

b.deposit(200) b.withdraw(100)

a.withdraw(200);

Schreibsperre für b

Warten auf

Schreibsperre für a Dann

Schreibsperre für b Alle Sperren

freigeben

Alle Sperren freigeben

(44)

Lösung 2: Erkennen (Detection)

‹ Deadlocks werden am Warte-Graph erkannt: enthält er einen Zyklus, ist das System in einem Deadlock.

– Dazu kann ein entsprechender Standard-Graphen-Algorithmus verwendet werden (Graphentheorie).

– Es muß dann eine Transaktion herausgesucht werden, deren Abbruch zum Brechen des Zyklus führt.

‹ Möglichkeit 1: verwende Timeouts.

– Eine Sperre einer Transaktion ist für eine bestimmte Zeit unverletzlich;

danach kann sie gebrochen werden (Deadlock kann u.U. für diese Zeit nicht aufgelöst werden!)

Verletzliche Sperren werden von Transaktionen gebrochen, die eine Sperre anfordern

– Eine Transaktion mit einer gebrochenen Sperre wird abgebrochen.

(45)

Deadlock: Beispiel

‹ T, U und V teilen eine Lesesperre für c, während W eine Schreibsperre für b besitzt, auf das V zugreifen möchte (links).

‹ Transaktionen T und W fordern nun eine Schreibsperre für Objekt c an (rechts).

‹ Jedes Objekt wartet nur auf ein Objekt, trotzdem ist V in zwei Zyklen.

‹ Lösung: breche V ab, dann werden die Zyklen aufgelöst

T

U

V

C

T

U Held by

Held by Held by

W

B Held by

(46)

Optimistische

Nebenläufigkeitskontrolle

(47)

Optimistische Nebenläufigkeitskontrolle

‹

Erkenntnis: Sperren hat einige gravierende Nachteile:

– Sperren müssen immer verwendet werden, auch wenn es gar nicht nötig wäre (z.B. nur read) → unnötiger Overhead

– Gefahr von Deadlocks

Reduzierung der Nebenläufigkeit durch spätes Abgeben von Sperren

‹

Alternative: verwende den optimistischen Ansatz, wenn es sehr selten Konflikte geben wird.

‹

Alle Transaktionen arbeiten, als wären sie die einzigen.

‹

Nur, wenn ein Konflikt auftritt, muß am Ende eine der

Transaktionen abgebrochen werden und deren Ergebnisse

(48)

Phasen der Transaktionen

Nach H.T. Kung und J.T. Robinson 1981

‹

Arbeitsphase (Working Phase):

Die Transaktion besitzt eine eigene Kopie (Versuchsversion) der notwendigen Daten und arbeitet auf diesen.

Bei read -Operationen: Wenn noch keine Kopie vorhanden ist, wird vom Original gelesen!

‹

Auswertungsphase (Validation Phase):

Nach Abschluß der Operationen der Transaktion wird

überprüft, ob es Konflikte mit anderen Transaktionen gab.

Wenn ja, müssen diese Konflikte gelöst werden.

‹

Aktualisierungsphase (Update Phase):

Wurde die Transaktion positiv validiert, werden die Daten permanent gemacht (festgeschrieben).

Implementierung als kritischer Bereich

vereinfacht die Auswertung!

Implementierung als kritischer Bereich

vereinfacht die Auswertung!

(49)

Auswertungsphase

‹

Natürlich werden auch hier die Konfliktregeln verwendet, um die serielle Äquivalenz mit allen überlappenden

Transaktionen zu garantieren.

‹

Überlappend: Transaktionen, die noch nicht festgeschrieben waren, als die neue Transaktion startete.

‹

Transaktionen werden durchnummeriert (Zeitstempel) in der Reihenfolge ihres Eintritts in die Auswertungsphase

(

closeTransaction

des Clients).

‹

Festschreibung: Transaktion T

i

wird dann vor Transaktion T

v

festgeschrieben, wenn i < v.

‹

Ist eine Transaktion ausschließlich lesend oder abgebrochen

(50)

Serialisierbarkeit einer Transaktion

‹

Der Auswertungstest für eine Transaktion T

v

basiert auf den Konflikten mit der überlappenden Transaktion T

i

.

‹

Um die Serialisierbarkeit herzustellen, müssen die folgenden Regeln erfüllt werden

(Ti < Tv, erstes write erzeugt eine Kopie!)

:

Tv Ti Regel

write read 1. Ti darf keine von Tv geschriebenen Objekte lesen read write 2.

write write 3.

Tv darf keine von Ti „geschriebenen“ Objekte lesen Ti darf keine von Tv geschriebenen Objekte schreiben und Tv von Ti „geschriebenen“ Objekte

>

Jüngere Transaktion Tvhat zu schnell gelesen oder ältere Transaktion Ti hat zu langsam geschrieben Jüngere Transaktion Tvhat zu schnell gelesen oder ältere Transaktion Ti hat zu langsam geschrieben Jüngere Transaktion Tv hat zu schnell geschrieben oder ältere Transaktion Ti hat zu langsam gelesen Jüngere Transaktion Tv hat zu schnell geschrieben oder ältere Transaktion Ti hat zu langsam gelesen

Jüngere Transaktion Tvhat zu schnell geschrieben oder ältere Transaktion Ti hat zu langsam geschrieben Jüngere Transaktion Tvhat zu schnell geschrieben oder ältere Transaktion Ti hat zu langsam geschrieben

(51)

Auswertungsstrategien

‹ Bei Rückwärtsauswertung werden die Regeln mit den vorhergehenden überlappenden Transaktionen - die vorher in die Auswertungsphase eingetreten sind überprüft.

‹ Bei Vorwärtsauswertung werden die Transaktionen einbezogen, die noch nicht in die Auswertungsphase eingetreten sind.

Zuvor bereits

mit der Auswertung begonnene

Transaktionen Arbeitet Auswertung Aktualisierung

T1 T2

aktuell ausgewer-

tete Transaktion Tv

Noch auszuwer-

active1

active T3

(52)

Auswertungsstrategien: Algorithmen

‹ Rückwärtsauswertung boolean valid = true;

//startTn größte Transaktions- nummer, als Tv startete

//finishTn + 1 = Tv

for (int Ti= startTn+1;

Ti <= finishTn; Ti++) {

// Regel 1 gilt // Tv > Ti

if (read_set of Tv intersects

write_set of Ti) valid = false; } // Regel 3 gilt

‹ Vorwärtsauswertung

boolean valid = true;

// active1 - 1 = Tv

for (int Ti= active1; Ti <= activeN; Ti++) {

// Regel 1 gilt // Ti > Tv

if (read_set of Ti intersects

write_set of Tv) valid = false; } // Regel 3 gilt

Regel 1 und 3 gelten, da Tv erst nach der Auswertungsphase geschrieben wird (und alle Ti mit i<v bereits

vorher festgeschrieben sind und

während der Arbeitsphase auf Kopien geschrieben haben!)

Regel 1 und 3 gelten, da Tv erst nach der Auswertungsphase geschrieben wird (und alle Ti mit i<v bereits

vorher festgeschrieben sind und

während der Arbeitsphase auf Kopien geschrieben haben!)

Regel 1 und 3 gelten, da Ti erst nach der Auswertungsphase von Tv

geschrieben wird!

Regel 1 und 3 gelten, da Ti erst nach der Auswertungsphase von Tv

geschrieben wird!

(53)

Ti

Tv

Original

Kopie write

read Ti darf keine von Tv geschriebenen Objekte lesen

Ti

Tv

Original Kopie

write

read

Tv darf keine von Ti geschriebenen Objekte lesen

Ti darf keine von Tv und Tv von Ti geschriebenen Objekte schreiben Original

write Ti

Kopie write

(54)

Zeitstempel-Reihenfolge

(55)

Zeitstempel-Reihenfolge

‹

Idee: jede Transaktion bekommt einen eindeutigen

Zeitstempel

ts(T)

(ermittelt mit Hilfe von Lamport-Uhren)

‹

Jede Operation einer Transaktion besitzt den Zeitstempel der Transaktion und wird sofort ausgewertet.

‹

Zeitstempelreihenfolge gibt serielle

Ausführungsreihenfolge der Transaktionen vor!

‹

Außerdem besitzt jedes Datenobjekt einen Lesezeitstempel

tsRD(x)

und einen Schreibezeitstempel

tsWR(x)

.

– tsRD(x)

enthält den Wert

ts(Ti)

, wobei

Ti

die Transaktion ist, die als letzte lesend auf

x

zugegriffen hat.

– tsWR(x)

enthält den Wert

ts(Ti)

, wobei

Ti

die Transaktion

(56)

Konfliktlösung

‹ Situation 1: der Planer erhält ein read(T,x) mit Zeitstempel ts.

– Wenn ts < tsWR(x), dann wurde die letzte write-Operation nach dem Start von T durchgeführt! T wird abgebrochen. Eine jüngere Transaktion hatte (zu früh) geschrieben.

– Wenn ts > tsWR(x), dann darf das read stattfinden. Eine ältere Transaktion hatte geschrieben.

Setze außerdem tsRD(x) auf max(ts,tsRD(x)).

‹ Situation 2: der Planer erhält ein write(T,x) mit Zeitstempel ts.

– Wenn ts < tsRD(x) ts < tsWR(x), dann wird T abgebrochen, da eine jüngere Transaktion x bereits gelesen oder geschrieben hat. T ist

sozusagen zu spät dran.

– Wenn aber ts > tsRD(x) ts > tsWR(x), dann darf der Wert von x geändert werden, da keine jüngere Transaktion den Wert gelesen oder geschrieben hat.

Setze außerdem tsWR(x) auf ts.

(57)

Zeitstempel-Reihenfolge: Beispiel

‹ Drei Transaktionen T1, T2, T3

‹ T1 wurde abgeschlossen, bevor T2 und T3 begannen, d.h. alle read- und write-Zeitstempel stehen auf ts(T1).

‹ T2 und T3 werden nebenläufig ausgeführt, mit ts(T2) < ts(T3).

‹ Die Transaktionen arbeiten ohne Kopien, also direkt auf dem Original.

‹ Betrachten wir einige Beispielsituationen (auf nächster Folie):

Schreiben:

 T2 schreibt x, ohne daß T3 bereits zugegriffen hätte [(a), (b)]

 T2 schreibt x, aber T3 hat vorher gelesen [(c)] oder geschrieben [(d)]

Lesen:

 T2 liest x ohne Konflikt [(e), (f)].

 In [(g)] hat T3 gelesen, T2 kann ohne Konflikt lesen.

(58)

Zeitstempel-Reihenfolge: Beispiel

Schreiben

Schreiben Lesen Lesen

(a)

tsRD(x) tsWR(x) ts(T2)

(T1) (T1) Zeit

(b)

tsWR(x) tsRD(x) ts(T2)

(T1) (T1) Zeit

(T2)

(T2)

(c)

tsWR(x) tsRD(x) ts(T2)

(T1) (T3) Zeit

(d)

tsRD(x) tsWR(x) ts(T2)

(T1) (T3) Zeit

(T2)

(T2)

OK

abort

(h)

tsRD(x) tsWR(x) ts(T2)

(T1) (T3) (T2) Zeit (e)

tsRD(x) tsWR(x) ts(T2)

(T1) (T1) Zeit

(f)

tsWR(x) tsRD(x) ts(T2)

(T1) (T1) Zeit

(T2)

(T2)

(g)

tsWR(x) tsRD(x) ts(T2)

(T1) (T3) (T2) Zeit

OK

abort

(59)

Zeitstempel-Reihenfolge: Beispiel 2

Um Abbrüche zu vermeiden, wird (wie bei der optimistischen Nebenläufigkeitskontrolle) mit Kopien gearbeitet

Original, d.h. write-Operationen wurden festgeschrieben

Kopie, d.h. write-Operationen wurden auf der Kopie ausgeführt

T

3

: write -Operation T

3

: write -Operation

T2 T3

T2 T2

Vor

Nach T1 T3

T1

T2

T4

T1 T4

T1

T3 T4

T4

T

3

: read -Operation T

3

: read -Operation

T2 T2 T4 T1 T2 T4

Fälle (d), (h) müssen so nicht abgebrochen werden, wenn die Kopie gehalten wird.

(60)

Nebenläufigkeitskontrolle: Reihenfolge

‹ Jede Nebenläufigkeitskontrolle sorgt stets für eine serielle Äquivalenz!

‹ Festlegung der Ausführungsreihenfolge für zwei „gleichzeitig“ gestartete Transaktionen U und T wird festgelegt

– Sperren: bei Vergabe der Sperren. U < T, T < U möglich.

– optimistische Nebenläufigkeitskontrolle: bei Eintritt in Auswertungsphase. U < T, T < U möglich.

– Zeitstempel-Reihenfolge: Beim Start der Transaktion

‹ Die Nebenläufigkeit sorgt für serielle Äquivalenz, ist aber für „unsinnigen Inhalt“ der Transaktionen nicht verantwortlich!

‹ Mit wachsender Anzahl an write-Operationen sollte von der optimistischen Nebenläufigkeit ohne Kopie zu der mit Kopie, dann zur Zeitstempel-

Reihenfolge ohne Kopie, dann mit Kopie und letztlich zu Sperren übergegangen werden.

‹ Die Entscheidung ist durch Beobachtung des eigenen Systems, d.h.

aussagekräftigen statistischen Untersuchungen, zu sichern bzw. zu treffen.

(61)

Nebenläufigkeitskontrolle: Vergleich

‹ Sperren

+ Gut geeignet für Transaktionen mit vielen Konflikten

Bei dominierenden read-Operationen ist Zeitstempel-Reihenfolge besser nicht Deadlock-frei

‹ optimistsiche Nebenläufigkeitskontrolle + Deadlock-frei

+ Maximale Ausnutzung von Nebenläufigkeit, deshalb sehr gut bei konfliktfreien Situationen

Transaktionen müssen manchmal wiederholt werden (vor allem schwierig unter hoher Last, Verhungern einer Transaktion möglich!)

‹ Zeitstempel-Reihenfolge + Deadlock-frei

Bricht Transaktionen auch ab, wenn es bei Sperren nicht nötig wäre

(62)

Wiederherstellung

(63)

Fehlerarten

Für Transaktionssysteme sind drei verschiedene Arten von Fehlern zu unterscheiden

‹

‹ TransaktionsfehlerTransaktionsfehler

Ursachen: Interne Konsistenzverletzung; Entscheidung des Transaktionsmanagementsystems

Häufigkeit: ca. 1 mal in der Sekunde

Maßnahmen: Jegliche Wirkung dieser Transaktion ungeschehen machen (undo)

Benötigte Zeit: etwa so lange wie eine erfolgreiche Transaktionsverarbeitung

‹‹ SystemabbruchSystemabbruch

Ursachen: Fehler im BS; Hardwareausfall (Stromversorgung); Fehler im Transaktionsmanagementsystems

(64)

Fehlerarten

Maßnahmen: Wiederherstellung des letzten bestätigten Zustands, evtl. Nachführen bestätigter aber verlorengegangener Änderungen (redo), evtl. Rückgängigmachen von Änderungen nicht bestätigter Transaktionen (undo)

Benötigte Zeit: ein paar Minuten

‹

‹ Ausfall von SpeichermedienAusfall von Speichermedien

Ursachen: Fehler im BS (Treibersoftware); Hardwarefehler: Kanal, Steuereinheit, Bus; Mechanische Zerstörung (head crash); Verlust der Magnetisierung

Häufigkeit: ca. 1 mal im Jahr

Maßnahmen: Kopien der Daten auf anderen Medien benötigt; Wenn Datenzustand nicht aktuell, müssen die Wirkungen aller seither

bestätigten Transaktionen nachgeführt werden (redo) – Benötigte Zeit: ca. 1 Stunde

(65)

Architektur eines Transaktionssystems

Datenmanagement (data manager)

Rücksetzer

(recovery manager)

read, write, lock, release, abort, commit

read, write

...

Stabiler Speicher

Log Instabiler

Speicher

Flüchtiger Speicher read

write

read write

read write

(66)

Das Log

‹ Das Log ist eine Repräsentation der Ausführung der Transaktionen.

‹ Im wesentlichen Einträge der Form (Ti, x, v), mit Ti

Transaktionsnummer, x Datenelement, v Wert für jede durchgeführte Schreiboperation.

‹ Einträge totalgeordnet und repräsentieren Ausführungsreihenfolge.

‹ Zusätzlich werden drei Listen unterhalten : – Liste der aktiven Transaktionen (active list)

– Liste der festgeschriebenen Transaktionen (commit list) – Liste der abgebrochenen Transaktionen (abort list)

‹ Ein Eintrag (Ti, x, v) im Log kann entfernt werden, wenn (1) Ti abgebrochen wurde (d.h. alles wiederhergestellt wurde) (2) Ti festgeschrieben wurde und eine andere festgeschriebene

Transaktion v den Wert x überschrieben hat (mit Ti < Tv)

‹ Das Wiederherstellen als Operation muß idempotent sein: Jede Folge unvollständig durchgeführter Wiederherstellungen gefolgt von einer

vollständigen Wiederherstellung muß dasselbe Ergebnis haben wie genau eine vollständige Wiederherstellung.

(67)

Wiederherstellungsverfahren

‹

Weitergabe von Änderungen

(Wo stehen festgeschriebene Daten ?)

: – FORCE Bei Festschreibung werden alle Änderungen der

Transaktion in den stabilen Speicher geschrieben

NOFORCE Nach Festschreibung einer Transaktion können sich geänderte Daten im flüchtigen Speicher befinden, die noch nicht "gerettet" wurden

‹

Ersetzungsstrategie

(Wo stehen noch nicht festgeschriebene Daten ?)

: – KEEP Alle Änderungen einer Transaktion werden bis zum

Festschreibungszeitpunkt im flüchtigen Speicher gehalten.

NOKEEP Der Datenmanager darf auch unbestätigte Daten

aus dem flüchtigen Speicher verdrängen

(68)

Wiederherstellungsverfahren

‹ Ziel:

– im flüchtigen Speicher ausschließlich nicht festgeschriebene Daten, – im stabilen Speicher ausschließlich festgeschriebene Daten.

‹ Operationen des Rücksetzers:

undo: Änderungen unbestätigter Transaktionen im stabilen Speicher müssen rückgängig gemacht werden

redo: Änderungen bestätigter Transaktionen im flüchtigen Speicher müssen nachgefahren werden.

‹ Je nach der eingesetzten Strategie (keep, force) kann auf redo und/oder undo verzichtet werden.

‹ Bei Keep/Force ist bei der Wiederherstellung nicht viel zu tun, allerdings muß im laufenden Betrieb erheblicher Aufwand getrieben werden.

‹ Bei Nokeep/Noforce ist ein effizienter Normalbetrieb möglich zu Lasten der aufwendigen Wiederherstellung

(69)

Verteilte Transaktionen

(70)

Verteilte Transaktionen

‹ Bisher haben wir Transaktionen betrachtet, die auf Objekte auf einem einzigen Server (Transaktionssystem) zugreifen (rechts).

‹ Oft jedoch werden die Objekte bzw. Operationen über mehrere Server und damit mehrere Transaktionssysteme verteilt (links).

‹ Zwei Arten von Diensten:

Nicht-transaktionale Dienste bieten keine Unterstützung für verteilte Transaktionen an, Dienstleistungen werden ohne besondere Garantien erbracht

Transaktionale Dienste bieten Unterstützung für verteilte Transaktionen an, unterliegen bei entsprechender Abstimmung globalen ACID-Garantien

‹ Beispiel: Buchung einer Reise

Flug Hotel

Bustransfers Tagesausflüge

Zwei unterschiedliche und unabhängige Datenbanken

Zwei physikalisch getrennte Teile einer Datenbank Geschachtelte Transaktion

Subtransaktion Subtransaktion

Geschachtelte Transaktion Subtransaktion Subtransaktion

(71)

Verteilte Transaktionen

‹

Verteilte Transaktionen können wiederum flach (oben) oder

geschachtelt (unten) sein.

‹

Bei einer flachen verteilten Transaktion greift der Client nacheinander auf die beteiligten Server zu.

‹

Bei der Verwendung von Subtransaktionen kann von der Nebenläufigkeit der

verschiedenen Server Gebrauch

X

Y

M

T1 N

T2

T11

Client T

T12 T21 Client

X

Y

Z T

(72)

Verteilte Transaktionen: Beispiel

Client

A

B

C T1

T2

T3

T4

T

D X

Y

Z

a.withdraw(10) T = openTransaction

openSubTransaction a.withdraw(10);

openSubTransaction b.withdraw(20);

openSubTransaction c.deposit(10);

openSubTransaction d.deposit(20);

closeTransaction

b.withdraw(20)

c.deposit(10) d.deposit(20)

(73)

Beispielarchitektur eines Transaktionssystems

T1

T1 TT22 TT33 Clients TTnn

Koord.

Koord. Koord.Koord. Koord.Koord. Verteilter

TA-Dienst Koord.Koord.

Scheduler Scheduler

Recovery Manager Recovery Manager

Log DB

Scheduler Scheduler

Recovery Manager Recovery Manager

Log DB

Scheduler Scheduler

Recovery Manager Recovery Manager

Log DB

Verteilte TA-Koordinatoren

• Vergabe von TA-Kennungen (TIDs)

• Zuordnung von TIDs zu Operationen

• Koordination von Festschreiben, Rücksetzen und Wiederanlauf Verteilte TA-Koordinatoren

• Vergabe von TA-Kennungen (TIDs)

• Zuordnung von TIDs zu Operationen

• Koordination von Festschreiben, Rücksetzen und Wiederanlauf

Lokale Scheduler

• Lokale Durchführung des 2PS-Prot.

• Lokale Sperrenverwaltung

• Lokale Warteschlangenverwaltung

• Lokale Verklemmungsüberwachung Lokale Scheduler

• Lokale Durchführung des 2PS-Prot.

• Lokale Sperrenverwaltung

• Lokale Warteschlangenverwaltung

• Lokale Verklemmungsüberwachung

Lokale Recovery Manager

• Führung der lokalen Protokolldatei

• Lokales Festschreiben von Transakt.

• Lokales Rücksetzen von Transakt.

• Lokaler Wiederanlauf nach Crash Lokale Recovery Manager

• Führung der lokalen Protokolldatei

• Lokales Festschreiben von Transakt.

• Lokales Rücksetzen von Transakt.

• Lokaler Wiederanlauf nach Crash

(74)

Koordination

‹ Zur korrekten Abwicklung der Transaktion müssen die Server ihre Aktionen koordinieren.

‹ Dazu wird für jede Transaktion ein Koordinator (Transaktionsmanager) bestimmt (typischerweise in einem der Server).

‹ Zum Start der Transaktion sendet der Client ein openTransaction() an den Koordinator.

– Dieser startet die Transaktion und liefert eine eindeutige Transaktions-ID (z.B. IP-Nummer + lokale TID) zurück.

– Der Koordinator entscheidet am Ende, ob eine verteilte Transaktion abgebrochen oder korrekt beendet wird.

‹ Er kennt alle Teilnehmer, die wiederum alle ihn kennen.

‹ Neue Teilnehmer melden sich mit der Methode

join(Transaktion,Verweis auf Teilnehmer) an.

‹ Zur Kooperation wird ein Commit-Protokoll (Festschreibungsprotokoll) verwendet.

(75)

Globale TID-Erzeugung und -Weiterleitung

Object Request Broker Object Request Broker Client

Client TA-KoordinatorTA-Koordinator

Log

Scheduler Scheduler

Recovery Manager Recovery Manager

Nicht-

Nicht- Transaktionaler

Dienst Transaktionaler

Dienst

Scheduler Scheduler

Recovery Manager Recovery Manager

Client ruft openTransaction()- Methode des TA-Koordinators auf.

Client ruft openTransaction()- Methode des TA-Koordinators auf.

(76)

Globale TID-Erzeugung und -Weiterleitung

Object Request Broker Object Request Broker Client

Client TA-KoordinatorTA-Koordinator

Log

Ressource 1 Ressource 1

Scheduler Scheduler

Recovery Manager Recovery Manager

Log DB Nicht-

transaktionaler Dienst Nicht- transaktionaler

Dienst

Transaktionaler Dienst ohne persistenten

Zustand Transaktionaler

Dienst ohne persistenten

Zustand Ressource 2Ressource 2

Scheduler Scheduler

Recovery Manager Recovery Manager

Log DB

TA-Koordinator erzeugt neue TID, kapselt diese als Transaktionsobjekt und protokolliert Existenz der TID.

TA-Koordinator erzeugt neue TID, kapselt diese als Transaktionsobjekt und protokolliert Existenz der TID.

LogLog

(77)

Globale TID-Erzeugung und -Weiterleitung

Object Request Broker Object Request Broker Client

Client TA-KoordinatorTA-Koordinator

LogLog

Scheduler Scheduler

Recovery Manager Recovery Manager

Nicht-

Nicht- Transaktionaler

Dienst Transaktionaler

Dienst

Scheduler Scheduler

Recovery Manager Recovery Manager

TA-Koordinator übergibt

Transaktionsobjekt als Kopie an Client, als Seiteneffekt wird dort

ein Request Interceptor („Anforderungs- abfänger“) installiert.

TA-Koordinator übergibt

Transaktionsobjekt als Kopie an Client, als Seiteneffekt wird dort

ein Request Interceptor („Anforderungs- abfänger“) installiert.

Referenzen

ÄHNLICHE DOKUMENTE

Entspricht canCommit?-Nachricht TA-Koordinator ermittelt Ressourcen, die an Transaktion beteiligt sind, und ruft auf jeder Ressource prepare()- Methode unter Angabe der TID

• Bei Anmeldung eines Objekts in der Registry oder beim Aufruf kann der Stub nicht ermittelt werden (nicht im CLASSPATH, nicht richtig angemeldet, nicht einzurichten.

So werden die überbetrieblichen Geschäftsprozesse, die primär Gegenstand von Verhandlun- gen zwischen den Agenten sind, durch Kommunikation und Verhandlungen bewertet, indem

Das Hessische Finanz- gericht ging in seiner Ent- scheidung davon aus, daß die vom Vater beglichenen Gerichts- und Anwaltsko- sten nur dann eine außer- gewöhnliche Belastung

Betriebsmittel, deren Nutzung zu einem konkreten Zeitpunkt höchstens einem Prozeß vorbehalten ist und nicht unterbrochen werden darf (Wechselseitiger Ausschluß –

 Bei Absturz aller wartenden Prozesse zwischen Freigabe der Ressource durch den letzten Prozeß in V(bSR) und Freigabe des Zählers durch den nächsten kann sich

Während ein Philosoph ißt, können sich seine beiden Nachbarn hungrig melden; in diesem Fall können sich die verbleibenden zwei Philosophen nicht mehr hungrig

Betriebsmittel, deren Nutzung zu einem konkreten Zeitpunkt höchstens einem Prozeß vorbehalten ist und nicht unterbrochen werden darf (Wechselseitiger Ausschluß –