Kap. 9 IS-Anwendungsentwicklung Beispiele: Relation Server

Werbung
Kap. 9 IS-Anwendungsentwicklung
9.1 Aufgabenteilung Client oder Server?
•Wieviel soll der Client machen?
Präsentation ok.
Anwendungsfunktionalität?
•Was sind die Aufgaben des Servers?
Datenverwaltung ok.
Anwendungsfunktionalität?
Server
Client
Data
Presentation
Anwendungs
Funktionalität
Data
Management
Anwendungsentwicklung - 1
ISK 2003
Beispiele: Relation Server
z
Client sendet
‹
SQL Queries oder Updates
‹ Stored-Procedures- Aufrufe
z
Server sendet
Application
Query Language
Interface
Communications Manager
‹
Tabellen als Menge von
Ergebnis-Tupeln
‹ Einfache Werte
z
Programmatic
Interface
...
SQL
Query
Result
Table
Procedure
Call
Result
Return
Beispiele:
‹
‹
‹
‹
‹
Oracle
Sybase
DB2
Informix
...relationale DBMS
Communications Manager
Query Optimizer
Index Manager
Stored Procedure
Transaction Manager
Page Cache Manager
Database
Database
ISK 2003
Anwendungsentwicklung - 2
Object Server
z
Client sendet
‹
Application
Objekt IDs
‹ Methodenaufrufe
z
Query Language
Interface
Server liefert
‹
Angefordertes Objekt im
Hauptspeicher des AP
‹ Ergebnis des Methodenaufrufs
z
Object
Browser
Programmatic
Interface
(Proxy) Object Manager
Method
Call
Objects
Beispiele: Objektorientierte
DBMS wie
‹
Gemstone
‹ Ontos
‹ Versant
Result
Return
Object Manager
Query Optimizer
Index Manager
Transaction Manager
Page Cache Manager
Database
Anwendungsentwicklung - 3
ISK 2003
Page Server
z
Client sendet
‹
z
Seitennummer
Server
‹
gibt Seite zurück
Application
Query Interface
& Optimizer
Object
Browser
Programmatic
Interface
Object Manager
z
Die eigentliche DBMS-Arbeit findet
daher im Client statt. Im Server
verbleibt “nur” die
Transaktionsverwaltung (zwangsläufig
auf der Seitenebene) und die
Pufferverwaltung.
Index Manager
Transaction Manager
Page Cache Manager
Pages
Transaction Manager
z
Beispiel:
Page Cache Manager
‹
O2
‹ Objectstore
ISK 2003
Database
Database
Anwendungsentwicklung - 4
9.2 Kopplungsvarianten zwischen Programmiersprachen
und Datenbanksprachen
1) Erweiterung der Programmiersprache um Datenbankkonstrukte: Persistente
Programmiersprachen, Datenbankprogrammiersprachen (z.B. Pascal/R, ODMG)
2) Erweiterung der Datenbanksprache um Programmierkonstrukte:
"4th Generation Languages" (4GLs, z.B. SQL99/PSM, PLSQL)
3) Einbettung der Datenbanksprache in die Programmiersprache:
"Embedded SQL" (ESQL) und Call-Level-Interface (CLI, z.B. ODBC, JDBC)
Kernproblem bei ESQL und CLI:
Abbildung von Tupelmengen auf die Datentypen der Wirtsprogrammiersprache
Realisierte Lösung:
Abbildung von Tupeln bzw. Attributen auf die Datentypen der
Programmiersprache
-> Wirtsprogrammvariable (engl.: Host Variables)
+
Iteratoren (Schleifen) zur Verarbeitung von Tupelmengen:
-> Cursor-Konzept
Anwendungsentwicklung - 5
ISK 2003
Client/Server, mehr Detail
Embedded
SQL Appl.
SQL
Commands
Call-level
SQL Appl.
Precompiler
CLI Calls
CLI
Precompiler
Call-level Interface
Run-time Library
Run-time Library
Database Driver
Stacks
Client
SQL FAP
Stacks
Server
Tables
Database
Server
Stored Procedures
aus: Orfali et al., 1999
ISK 2003
Anwendungsentwicklung - 6
9.3 Anwendungsentwicklung - Client-seitig
z
z
Embedded SQL (ESQL):
Nach ISO SQL-92 definierte Einbettung von SQL in
Programmiersprachen, z.B. Cobol, PL/1, Pascal, C, Java,...
‹
Statisches ESQL: Alle Informationen zur Compilierung vorhanden
‹
Dynamisches ESQL: SQL-Statements erst zur Laufzeit bekannt
Call-Level Interface (CLI):
Standardisierte Schnittstelle zur Kommunikation mit
Datenbanken ohne Precompiler
‹
‹
X/Open SAG CLI (SAG = SQL Access Group)
ODBC, JDBC
Anwendungsentwicklung - 7
ISK 2003
Wirtsprogrammvariable (Host Variables)
Die Attribute eines Resultattupels einer SQL-Anfrage werden an speziell deklarierte
Variable des Wirtsprogramms zugewiesen (INTO-Klausel).
Beispiel:
EXEC SQL
SELECT PNr, Menge, Status INTO :pnr, :menge, :status
FROM Bestellungen WHERE BestNr = 555;
Analog können SQL-Anweisungen mittels solcher Variable mit Eingabeparametern
versorgt werden:
Beispiele:
1)EXEC SQL SELECT PNr, Menge, Status INTO :pnr, :menge, :status
FROM Bestellungen WHERE BestNr = :bestnr;
2)EXEC SQL INSERT INTO Bestellungen (BestNr,Monat,Tag,KNr,PNr, Menge)
VALUES (:bestnr, :monat, :tag, :knr, :pnr, :menge);
Wirtsprogrammvariable dienen als "Übergabepuffer" zwischen DBS und Programm.
Generell werden dabei die SQL-Datentypen auf die Datentypen der jeweiligen
Wirtsprogrammiersprache abgebildet.
ISK 2003
Anwendungsentwicklung - 8
Indikatorvariable zum Erkennen von Nullwerten
Beispiel:
EXEC SQL BEGIN DECLARE SECTION;
int
pnr;
int
vorrat;
short
vorrat_ind;
EXEC SQL END DECLARE SECTION;
...
EXEC SQL
SELECT Vorrat INTO :vorrat:vorrat_ind
FROM Produkte WHERE PNr = :pnr;
if (vorrat_ind == 0)
{ /* kein Nullwert */ ... }
else
{ /* Nullwert */ ... };
Allgemein können Indikatorvariable folgende Werte haben:
=0
die entsprechende Wirtsprogrammvariable hat einen regulären Wert
=-1
die entsprechende Wirtsprogrammvariable hat einen Nullwert
>0
die entsprechende Wirtsprogrammvariable enthält eine
abgeschnittene Zeichenkette
Anwendungsentwicklung - 9
ISK 2003
Verarbeitung von Tupelmengen mittels CursorKonzept
Zweck: Verarbeitung von Tupelmengen in einer nichtmengenorientierten
Wirtsprogrammiersprache. Notwendig für alle Anfragen mit mehr als einem
Resultattupel.
Beispiel: Ausgabe aller Bestellungen eines Kunden
#define TRUE 1
#define FALSE 0
...
printf ("Bitte geben Sie eine Kundennummer ein. (0 = Programmende)\n");
scanf ("%d", &knr);
EXEC SQL DECLARE Kundeniterator CURSOR FOR
SELECT Monat, Tag, Bez, Menge
FROM Bestellungen WHERE KNr = :knr
ORDER BY Monat DESC, Tag DESC;
/* Cursor-Deklaration immer ohne INTO-Klausel */
ISK 2003
Anwendungsentwicklung - 10
EXEC SQL OPEN Kundeniterator;
/* An dieser Stelle werden die Eingabeparameter der SQL-Anweisung (:knr)
ausgewertet,und gedanklich wird hier die Resultattupelmenge ermittet*/
found = TRUE;
while (found) /* solange es noch Resultattupel gibt */
{
EXEC SQL FETCH Kundeniterator INTO :monat, :tag, :bez, :menge;
/* Hier werden die Wirtsprogrammvariable für die Resultattupel festgelegt.
*/
bez.arr[bez.len] = '\0';
if ((sqlca.sqlcode >= 0) && (sqlca.sqlcode != 1403))
printf ("%d.%d.: %d %s", tag, monat, menge, bez);
else
found = FALSE;
}; /*while*/
EXEC SQL CLOSE Kundeniterator;
/* Freigabe des Cursors und der damit verbundenen DBS-Ressourcen */
Anwendungsentwicklung - 11
ISK 2003
Fehlerbehandlung in ESQL
1)Explizites Testen von sqlca.sqlcode im Wirtsprogramm nach einer SQL-Anweisung:
=0
Anweisung korrekt ausgeführt, keine besonderen Vorkommnisse
<0
Fehler bei der Ausführung (siehe Fehlercodes im Manual)
>0
Anweisung ausgeführt, Auftreten eines Sonderfalls,
z.B. signalisiert der Wert 1403, dass keine (weiteren) Treffertupel existieren
Zusatzinformation in den restlichen Komponenten von sqlca, z.B.:
sqlca.sqlerrd[2]
Anzahl der Tupel, die von einer
Insert-, Update- oder Delete-Anweisung betroffen waren
sqlca.sqlerrm.sqlerrmc Fehlermeldung als Ascii-Text (max. 70 Zeichen)
sqlca.sqlerrm.sqlerrml Länge der Fehlermeldung
2)Deklaration von "Exception-Handling"-Strategien:
EXEC SQL WHENEVER ( SQLERROR | NOT FOUND | SQLWARNING )
( STOP | GOTO label | CONTINUE )
wobei
SQLERROR einem SQLCODE < 0 entspricht,
NOT FOUND dem SQLCODE 1403 und
SQLWARNING einem SQLCODE > 0 (aber ungleich 1403).
Der ESQL-Precompiler erzeugt automatisch nach jeder SQL-Anweisung
einen entsprechenden Vergleich mit sqlca.sqlcode, und zwar jeweils aufgrund
der textuell letzten WHENEVER-Anweisung vor der SQL-Anweisung.
ISK 2003
Anwendungsentwicklung - 12
Embedded SQL - statisch
ESQL/Csource
program
ESQL/C
precompiler
C-source
program
with SQL
statements
and ESQL/C
calls
C language
preprocessor
and
compiler
Executable
Programm
Beispiel:
credit (int amount, int accountno) {
EXEC SQL UPDATE account
SET balance = balance + :amount
WHERE account_number = :accountno;
}
z
Zur Compilezeit hat der Precompiler u.a. folgende Aufgaben:
‹
‹
‹
z
Syntax- und Semantikprüfung
Typenprüfung
Fehlerbehandlung
Wenig flexibel, aber weniger Laufzeitfehler!
Anwendungsentwicklung - 13
ISK 2003
Embedded SQL - dynamisch
ESQL/Csource
program
ESQL/C
precompiler
C-source
program
with SQL
statements
and ESQL/C
calls
C language
preprocessor
and
compiler
Executable
Programm
Beispiel:
credit( int amount, int accountno, char *table) {
char dyn_stmt[120];
sprintf(dyn_stmt,
"UPDATE %s SET balance = balance + :a
WHERE account_number = :ano“, table);
EXEC SQL PREPARE sql_stmt FROM :dyn_stmt;
EXEC SQL EXECUTE sql_stmt USING :amount, :accountno;
}
z
z
ISK 2003
Der Precompiler kann weniger Überprüfungen durchführen, da das SQL
Statement erst zur Laufzeit bekannt ist.
Flexibler, aber mehr Laufzeitfehler möglich!
Anwendungsentwicklung - 14
Call Level Interface, SQL99 CLI:
#include "sqlcli.h"
extern SQLHDBC hdbc;
extern SQLHENV henv;
/* Verbindung steht schon */
/* Umgebung */
API
CLI
Native
Interface
DBMS
void credit ( SQLHSTMT hstmt,
int amount, int accountno, char *table) {
/* hstmt wird von aussen gegeben, damit Transaktionskontrolle ausserhalb
dieser Prozedur. "credit" ist Baustein */
char update[120];
SQLINTEGER NameParamLength1;
SQLINTEGER NameParamLength2;
sprintf(update, "UPDATE %s SET balance = balance + ? WHERE account_number
= ?", table);
SQLPrepare(hstmt, update, SQL_NTS);
SQLBindParameter(hstmt, 1, SQL_PARAM_MODE_IN, SQLCHAR, SQL_CHAR,
NAME_LENGTH, 0 &amount, NAME_LENGTH, &NameParamLength1);
SQLBindParameter(hstmt, 2, SQL_PARAM_MODE_IN, SQLCHAR, SQL_CHAR,
NAME_LENGTH, 0 &accountno, NAME_LENGTH, &NameParamLength2);
SQLExecute(hstmt);
}
ISK 2003
Anwendungsentwicklung - 15
Zusammenfassung Client-seitige AP
z
z
z
z
z
Jeder Anwender programmiert selbst und entwickelt ähnliche
Bausteine.
Besser wäre: Anwender benutzen Funktions-Bausteine!
Bausteine ändern sich (Systemwechsel oder Firmenpolitik).
Folge: alle Anwender müssen ihre Programmierung ändern
bzw. Module aus gemeinsamer Bibliothek holen.
Besser: Funktions-Bausteine in der Datenbank abgelegen.
Damit können alle Clients darauf zugreifen.
Also „Stored Procedures“ in die Datenbank ->9.4!
Beachten: Dies ist unabhängig von Performance-Aspekten!
ISK 2003
Anwendungsentwicklung - 16
9.4 Anwendungsentwicklung - Server-seitig
z
z
z
Stored Procedures:
- Verwendung einer “Stored Procedure Language”, z.B. PL/SQL
- Standard unter SQL-99 als “SQL/PSM” (= Persistent Stored Module)
Trigger (ereignisgesteuerte Funktionen/Prozeduren)
User Defined Types (UDTs, s. SQL-99)
Client
Client
Application
Select
Insert
Application
Update
Execute
procedure
Return
results
Stored
Procedure
Server
Database
Remote SQL
Database Server
Stored Procedure
Anwendungsentwicklung - 17
ISK 2003
PSM aus SQL99
Erweiterung von SQL zur Programmiersprache: Wir finden die üblichen
Konstrukte aus höheren Programmiersprachen...
- compound statement
- SQL variable declaration
- if statement
- case statement
- loop statement
- while statement
- repeat statement
- for statement
- leave statement
- return statement
- call statement
- assignment statement
- signal / resignal statement
ISK 2003
BEGIN … END;
DECLARE var CHAR (6);
IF subject (nachr) < > ‘urgent’
THEN … ELSE …;
CASE subject (nachr)
WHEN ‘SQL’ THEN …
WHEN …;
LOOP <SQL statement list> END LOOP;
WHILE i < 100 DO … END WHILE;
REPEAT … UNTIL i < 100 …
END REPEAT;
FOR result AS … DO … END FOR;
LEAVE …;
RETURN ‘urgent’;
CALL procedure_x (1, 3, 5);
SET x = ‘abc’;
SIGNAL division_by_zero
Anwendungsentwicklung - 18
Beispiel für SQL-Prozedur
Beispiel in Oracle
CREATE PROCEDURE debit (
amount NUMBER, accountno INT, result OUT INT) IS
bal INT;
BEGIN
SELECT balance INTO bal FROM account
WHERE account_number = accountno;
IF bal > amount THEN
UPDATE account SET balance = balance - amount
WHERE account_number = accountno;
result = 1;
ELSE
result = 0;
END IF;
END debit;
Anwendungsentwicklung - 19
ISK 2003
9.5 Java und Datenbankprogrammierung
Im Folgenden werden wir am Beispiel von SQLJ zeigen, wie man eine
Funktion sowohl server- als auch client-seitig verwenden kann. Folgendes
sind wichtige Tatsachen:
z
SQLJ ist entstanden auf Vorschlag von ORACLE, aber u.a. auch von IBM,
Sybase, Informix unterstützt.
Der Precompiler von ESQL wird bei SQLJ üblicherweise “Translator” genannt.
SQLJ erzeugt JDBC, eine standardisierte Call-Schnittstelle
z
SQL-Anweisungen haben die allgemeine Form:
z
z
#sql { SQL-Anweisung };
ISK 2003
Anwendungsentwicklung - 20
Debit als Java-Funktion (mit SQLJ)
public static int debit (int amount, int accountno)
throws SQLException
{
/* File connect.properties enthaelt alle noetigen Parameter */
Oracle.connect(Account.class, "connect.properties");
int bal;
#sql{
SELECT balance INTO :bal FROM account
WHERE account_number = :accountno
};
/* Abbuchen falls moeglich... */
if (bal > amount) {
#sql{ UPDATE account
SET balance= balance - :amount
WHERE account_number = :accountno
};
#sql { COMMIT };
return 1;
}else {
return 0;
}
}
Anwendungsentwicklung - 21
ISK 2003
SQLJ: client-seitig
public static void main( String args[] )
{
try {
if (args.length != 2) { System.out.println("Usage: java Account <amount> <accountnum
} else {
int amount = Integer.parseInt(args[0]);
int account = Integer.parseInt(args[1]);
if ( debit(amount,account)==1) {
System.out.println( "Abbuchung okay...");
}else {
System.out.println( "Abbuchung konnte nicht ausgefuehrt werden...");
}
}
} catch( SQLException exception ) {
System.err.println( "Error running the example: " + exception );
}
}
}
Compilieren und aufrufen mit:
sqlj -explain -ser2class -status Account.sqlj
java Account
ISK 2003
Anwendungsentwicklung - 22
SQLJ : server-seitig (I)
alter java class "Account" compile;
create or replace package AccountPack as
FUNCTION debit(amount NUMBER, accountno NUMBER)
RETURN NUMBER;
end AccountPack;
/
create or replace package body AccountPack as
FUNCTION debit(amount NUMBER, accountno NUMBER)
RETURN NUMBER
AS
language java
name 'Account.debit(int,int) return int';
end AccountPack;
/
In den Oracle-Server laden mit:
jar cvf0 Account.jar *.class
loadjava -thin -user iskXX/iskXXX@dblab3:1521:stud3 -resolve
Account.jar
Anwendungsentwicklung - 23
ISK 2003
SQLJ : server-seitig (II)
Verwendung wie "gewöhnliche" Stored Procedure:
DECLARE dummy NUMBER;
BEGIN
dummy := AccountPack.debit(300,1);
END;
/
SELECT * from account;
ISK 2003
Anwendungsentwicklung - 24
SQLJ-Cursor (I): “named iterators”
#sql iterator MyNamedIterType ( int legiNr, String name);
MyNamedIterType myIter1;
Beispiel-Tabelle:
iskdb (legiNr, name)
#sql myIter1 = { SELECT name , legiNr FROM iskdb };
while (myIter1.next ()) {
System.out.println ("Legi: "+ myIter1.legiNr() + " Name: " + myIter.name() );
}
myIter1.close();
Benannte Iteratoren (named iterators):
‹
‹
flexibler; Zuordnung über Namen
kann vom SQLJ-Translator (= Preprocessor) geprüft werden
Anwendungsentwicklung - 25
ISK 2003
SQLJ-Cursor (II): “positional iterators”
#sql iterator MyPosIterType (int, String);
MyPosIterType myIter2;
int legiNr;
String name;
Beispiel-Tabelle:
iskdb (legiNr, name)
#sql myIter2 = { SELECT legiNr, name FROM iskdb };
while (true) {
#sql { FETCH :myIter2 INTO :legiNr, :name };
if ( myIter2.endFetch() ) break;
System.out.println ("Legi: "+ legiNr + " Name: " + name );
}
myIter2.close();
Positionsiteratoren (positional iterators):
‹ Zuordnung allein über Position
‹ fehleranfälliger
‹ explizite FETCH-Anweisung nötig.
ISK 2003
Anwendungsentwicklung - 26
Ausblick Java-Programmierung
EJBs (siehe Vertiefung)
z
‹
‹
‹
‹
Standardisierte Laufzeitumgebung für in Java geschriebene
Komponenten (Beans)
Deklarative Bestimmung der Persistenzeigenschaften der Beans
Standardfunktionalität schon durch Laufzeitumgebung implementiert
Beispiele: Transaktionen, Persistenz, Object-Pooling,...
Literatur:
Seite des SQLJ-Konsortiums: www.sqlj.org
“SQLJ Online Manual Oracle Version 8”, (lokal auf http://www.dbs.ethz.ch/~oracle/)
NE
U
C. Türker: SQL:1999 & SQL:2003 - Objektrelationales SQL, SQLJ & SQL/XML, dpunkt-verlag,
2003. ISBN: 3-89864-219-4. [IH.03.8]
G. Saake, K.-U. Sattler: “Datenbanken & Java. JDBC, SQLJ und ODMG”, dpunkt.verlag, 2000,
(ISBN 3-932588-54-1)
Anwendungsentwicklung - 27
ISK 2003
9.6 Verteilte Transaktionen
Ziel dieses Unterkapitels:
Einblick gewinnen, welche Probleme auftreten, wenn Transaktionsgarantien in
Anwendungen gefordert werden, die mehrere Datenbanken umspannen und
welche Lösungen es dazu gibt. Vorbereitung für Transaktionsverwaltung auf
höherer Ebene und auf mehreren Ebenen (Kap. 11).
Klienten, die
Transaktionen über
mehrere Datenbanken
verlangen
Generelles Szenario:
DB1
ISK 2003
DB2
...
DBk
Anwendungsentwicklung - 28
Korrektheit verteilter Transaktionen
Bezeichnungen: Klienten definieren Transaktionen Ti = (ti1, ti2, ...tik) , die
in Teilaufträge (= Subtransaktionen) tij an die betroffenen "KomponentenDatenbanken" zerlegt werden. Jede Subtransaktion ist eine Folge von
Datenbankaktionen. Wir nehmen an, dass zwischen den
Subtransaktionen einer Transaktion eine partielle Ordnung definiert ist,
d.h. gewisse Subtransaktionen können und werden parallel ausgeführt.
Zur Vereinfachung nehmen wir an, dass es pro Transaktion Ti nur eine
Subtransaktion pro Komponentendatenbank gibt.
Beispiel:
t12= (R12(d),W12(d))
T1 = (t11, t12) mit t11= (R11(a), R11(b))
t22= (R22(d),W22(c))
T2 = (t21, t22) mit t21= (W21(a), W21(b))
DB1
DB2
Schedule:
S1 = (R11(a),R11(b),W21(a),W21(b))
Serialisierungsordnung: T1 < T2
Schedule:
S2 = (R22(d),R12(d),W22(c),W12(d))
Serialisierungsordnung: T2 < T1
Anwendungsentwicklung - 29
ISK 2003
Beobachtung: Der Ablauf im vorigen Beispiel ist nicht korrekt. Es gibt keinen seriellen
Ablauf mit diesen Konfliktpaaren.
⇒
Wir müssen die Serialisierungsordnungen kennen und dafür sorgen, dass sie in
allen Komponentendatenbanken gleich sind.
Satz: Beim strikten 2PL stimmt die Serialisierungsreihenfolge mit der
Commitreihenfolge überein.
Beweisüberlegung: Eine Kante T1→T2 bedeutet beim S2PL, dass T2 die Ausführung
erst dann beginnen und somit auch beenden kann, wenn T1 "committed" hat.
Anwendung: Durch Vorgabe der gleichen Commit-Reihenfolge in allen KomponentenDatenbanken erzwingen wir die gleiche Serialisierungsreihenfolge und damit Korrektheit
der (verteilten) Transaktionen Ti.
Bedenken: Wir können Commits nicht erzwingen!!
Integritätsverletzung einer Subtransaktion verhindert Commit, und führt dort auf ABORT
lokale Deadlocks sind nicht vermeidbar, Systemabstürze kommen zu nicht geplanten
Zeitpunkten,...
⇒ Wir brauchen atomares Commit für alle Komponenten-DB ⇒
ISK 2003
nächstes Unterkapitel
Anwendungsentwicklung - 30
Atomarität verteilter Transaktionen
Problem: Zusätzlich zu den Logging-Massnahmen der beteiligten Komponenten-Systeme
ist ein verteiltes Protokoll notwendig, um das Commit oder Rollback der Transaktion in
allen Systemen einheitlich durchzuführen. Es darf nicht passieren, dass ein System einen
Commit-Logsatz für die Transaktion schreibt, während ein anderes System seinen Teil der
Transaktion zurücksetzt. Zusätzlich müssen verschiedene Arten von Nachrichtenfehlern
(verlorene Nachrichten, duplizierte Nachrichten) verkraftet werden.
2-Phasen-Commit-Protokoll (2PC)
Grundprinzip: Eines der beteiligten Systeme wird zum Koordinator für den Ablauf des
Commit einer Transaktion bestimmt. Es kann z.B. immer das System gewählt werden,
von dem aus die Transaktion gestartet wurde. Die anderen Systeme werden als
Agenten bezeichnet. Das Protokoll läuft dann in zwei Phasen ab:
– Phase 1: Der Koordinator fragt alle Agenten, ob sie in der Lage sind, die
Transaktion mit Commit zu beenden, und bittet die Agenten gleichzeitig, sich
sowohl auf ein Commit als auch ein Rollback vorzubereiten (“Prepare”-Nachricht).
Im positiven Fall gehen dann alle Agenten in den Zustand “prepared” über.
– Phase 2: Aufgrund des Umfrageergebnisses trifft der Koordinator eine globale
Entscheidung für die Transaktion und teilt diese allen Agenten mit. Nur wenn alle
Agenten positiv geantwortet haben, kann der Koordinator eine CommitEntscheidung treffen. Andernfalls muss seine Entscheidung “Rollback” lauten.
Anwendungsentwicklung - 31
ISK 2003
2 PC Hintergrundinformation
In der Zeit zwischen dem Antworten eines Agenten und dem Erhalt der KoordinatorEntscheidung kann ein Agent keine eigenmächtige Entscheidung treffen. Insbesondere
muss der Agent weiterhin alle Sperren für die Transaktion halten, da ein Rollback immer
noch möglich ist. Da der Koordinator ausfallen kann oder die Nachricht mit seiner
Entscheidung verloren gehen kann, können Agenten auf diese Weise in eine gewisse
Blockierungssituation geraten, die sich sehr negativ auf die Leistung des betroffenen
Systems auswirken kann. Man bezeichnet aus diesem Grund das 2PC auch als ein
blockierendes Commit-Protokoll. (Man kann beweisen, dass es — unter Berücksichtigung
aller möglichen Fehlerfälle — kein nichtblockierendes verteiltes Commit-Protokoll geben
kann.)
Bemerkung:
• Das 2PC ist standardisiert (ISO/OSI, X/Open). Es wird von praktisch allen kommerziellen
DBS unterstützt, wobei diese sowohl in die Koordinator- als auch in die Agentenrolle
schlüpfen können. In vielen Systemumgebungen, insbesondere wenn verschiedene
DBS zum Einsatz kommen, wird die Koordinatorrolle von einem TP-Monitor
(Transaction Processing Monitor, -> Vertiefung) übernommen.
ISK 2003
Anwendungsentwicklung - 32
Nachrichten und Zustände des 2PC im Erfolgsfall:
Koordinator
Agent 1
Agent 2
Schreibe Begin-Logsatz
auf stabilen Speicher
PREPARE-TO-COMMIT
Undo/Redo auf
stabilen Speicher
OK
Undo/Redo auf
stabilen Speicher
OK
Schreibe Commit-Logsatz
auf stabilen Speicher
COMMIT
EOT
ACK
EOT
ACK
Schreibe End-Logsatz
auf stabilen Speicher
Anwendungsentwicklung - 33
ISK 2003
Behandlung von Nachrichtenverlusten
Falls bei einem Knoten eine — aufgrund des Protokolls — erwartete Nachricht nicht
innerhalb einer bestimmten Frist eintrifft (sog. Timeout), wird angenommen, dass der
Sender ausgefallen ist, und der Empfänger verhält sich wie bei einem Knotenausfall.
Behandlung von Knotenausfällen
Ausfallender Knoten
Reaktion Koordinator
Koordinator
in Phase 1
(vor dem Schreiben des
"Commit"-Logsatzes)
Nach dem Restart:
Wiederholung des Sendens
der "Prepare"-Nachricht
-
Koordinator
in Phase 2
(vor dem Schreiben des
"End"-Logsatzes)
Agent in Phase 1
(vor dem Schreiben des
"Prepared"-Logsatzes)
Agent in Phase 2
(vor dem EOT)
ISK 2003
Reaktion des Agenten
Falls noch nicht "prepared":
Warten oder einseitiges Abort
Falls bereits "prepared":
Warten (Blockierung) oder
ggf. andere Agenten fragen
Nach dem Restart:
- Vor dem EOT:
Wiederholung des Sendens
Warten (Blockierung) oder
der "Commit"- oder
ggf. andere Agenten fragen
"Abort"-Nachricht
- Nach dem EOT:
Wiederholung des "Ack" bei
wiederholtem Empfang der
"Commit"- oder "Abort"-Nachricht
Bei ausbleibendem Votum: Nach dem Restart:
Wiederholung des Sendens Einseitiges Abort
der "Prepare"-Nachricht
Bei ausbleibendem "Ack": Nach dem Restart:
Wiederholung des Sendens Warten auf Nachricht des Koordinators
der "Commit"- oder
(Wiederholte "Prepare"-Nachricht oder
"Abort"-Nachricht
(wiederholte) "Commit"/"Abort"-Nachricht)
oder Nachfragen beim Koordinator
Anwendungsentwicklung - 34
Anhang: Syntaxdiagramme für (E)SQL
column_element
CREATE TABLE
)
(
table
table_constraint
,
column_element
ALTER TABLE
table
ADD
table_constraint
NULL
DEFAULT
column_element
DROP TABLE
column
column_constraint
value
data_type
table
VARCHAR
(
INTEGER
)
(
INTEGER
)
(
INTEGER
)
BIT
data_type
INTEGER
FLOAT
,
DECIMAL
(
INTEGER
)
INTEGER
Anwendungsentwicklung - 35
ISK 2003
constraints
NOT NULL
UNIQUE
column_constraint
PRIMARY KEY
referential_action
REFERENCES
(
table
(
CHECK
)
column
search_condition
)
,
UNIQUE
(
)
column
PRIMARY KEY
,
table_constraint
(
FOREIGN KEY
)
column
REFERENCES
,
table
(
)
column
referential_action
CHECK
referential_action
(
search_condition
ON UPDATE
CASCADE
ON DELETE
SET NULL
)
SET DEFAULT
NO ACTION
CREATE ASSERTION
assertion
CHECK
(
search_condition
)
query
*
ALL
select_block
SELECT
expression
DISTINCT
,
,
FROM
table
correlation_var
WHERE
search_condition
,
GROUP BY
HAVING
search_condition
column
unordered_query
select_block
UNION
INTERSECTION
EXCEPT
INTEGER
ordered_query
unordered_query
DESC
ORDER BY
column
ASC
,
data manipulation
INSERT INTO
(
table
)
column
,
VALUES
(
)
expression
,
(
unordered_query
)
,
NULL
UPDATE
table
SET
column
=
expression
(
unordered_query
WHERE
DELETE FROM
ISK 2003
table
WHERE
)
search_condition
search_condition
Anwendungsentwicklung - 38
expression
expression
column
value
*
(
COUNT
)
ALL
column
DISTINCT
MAX
(
)
expression
MIN
DISTINCT
SUM
(
)
expression
AVG
/
+
*
Anwendungsentwicklung - 39
ISK 2003
search condition
search_condition
NOT
expression
BETWEEN
NOT
NOT
AND
expression
expression
_
expression
string
"
LIKE
"
%
column
(
expression
IS
)
NULL
NOT
=
<>
expression
ANY
>
expression
>=
(
unordered_query
ALL
,
<
OR
<=
AND
expression
value
IN
(
NOT
EXISTS
ISK 2003
(
)
)
unordered_query
unordered_query
)
Anwendungsentwicklung - 40
view, access rights
WITH CHECK OPTION
CREATE VIEW
(
table
)
column
AS
ordered_query
,
WITH GRANT OPTION
GRANT
access_right
ON
table
TO
PUBLIC
user
,
GRANT OPTION FOR
REVOKE
access_right
ON
table
FROM
PUBLIC
user
,
SELECT
INSERT
access_right
UPDATE
DELETE
ALL PRIVILEGES
Anwendungsentwicklung - 41
ISK 2003
embedded sql
DECLARE
cursor
OPEN
cursor
FETCH
cursor
CURSOR FOR
ordered_query
:
INTO
variable
,
CLOSE
cursor
DELETE FROM
table
CURRENT OF
WHERE
cursor
,
NULL
UPDATE
table
SET
column
=
expression
(
WHERE
unordered_query
CURRENT OF
)
cursor
Herunterladen