Friedrich-Schiller-Universität Jena Fakultät für Mathematik und Informatik Institut für Informatik Lehrstuhl für Datenbanken und Informationssysteme Prof. Dr. Klaus Küspert Dipl.-Inf. B. Pietsch Datenbanksysteme 2 Übungsblatt 5 SS 2014 Ausgabe: 18.06.2014 Aufgabe 1 Besprechung: 24.06.2014 BOCC und FOCC Gegeben sei folgende von drei Transaktionen erzeugte Operationsfolge: r1 (x), r2 (x), r1 (y), r3 (x), w1 (x), w1 (y), c1 , r2 (y), r3 (z), w3 (z), c3 , r2 (z), c2 Die Operationen sind folgendermaßen zu verstehen: ri (d) : Transaktion i liest das Datenelement d wi (d) : Transaktion i schreibt das Datenelement d ci : Transaktion i endet mit einem Commit Wie wird diese Operationsfolge bei Anwendung von FOCC und BOCC ausgeführt? Erläutern und begründen Sie Ihre Antwort! Die genauere Beschreibung der hier genutzten BOCC- und FOCC-Verfahren finden Sie im Web unter: http://www.informatik.uni-jena.de/dbis/lehre/ss2014/dbs2/uebung/occ.pdf Für das FOCC-Verfahren soll dabei angenommen werden, daß im Konfliktfall jeweils die sich in der Validierungsphase befindliche Transaktion abgebrochen wird. Zusatzinformationen bei Bedarf Optimistic Concurrency Control Annahme: nur selten Konflikte zwischen TAen ==> präventives Sperren oft unnötig • TAen dürfen beliebig operieren • am Ende erfolgt Konfliktprüfung und -auflösung 3 Phasen: • Lesephase TA führt alle ihre Operationen aus jedoch werden veränderte Datenblöcke isoliert ==> nach außen nicht sichtbar • Validierungsphase Prüfung ob es zu Konflikten mit anderen TAen gekommen ist • Schreibphase Wenn die Validierungsphase erfolgreich positiv abgeschlossen wurde, werden die in der Lesephase vorgenommenen Veränderungen allen anderen TAen zugänglich gemacht BOCC & FOCC jede TA verwaltet zwei Mengen: • Read-Set (RS) Menge aller gelesener Objekte • Write-Set (WS) Menge aller geänderten Objekte • dabei wird nicht festgehalten zu welchem Zeitpunkt die Objekte zu der Menge hinzugefügt wurden T1 r(x) L T2 T3 L L r(y) w(y) V S VS w(y) V S Abbildung 1: Hierarchie von Datenbankobjekten BOCC - backward oriented OCC • Validierung erfolgt über bereits beendete TAen • validierende TA prüft, ob eine beendete TA ein Datum geändert hat, das sie selbst gelesen hat (wenn ja potentiell alte Daten gelesen) • validierende TA wird zum Rollback gezwungen Beispiel Für unser Beispiel ergibt sich mit BOCC folgendes: • T2: zum Validierungszeitpunkt ist keine andere TA bereits beendet (die von T3 vorgenommene Änderung von y ist noch nicht global sichtbar), somit kann T2 ohne Probleme geschrieben werden • T3: T2 ist beendet, der Durchschnitt RST 3 ∩W ST 2 = ∅ somit gibt es keine Konflikte zwischen beiden TAen, T3 kann beendet werden • T1: hat den Wert x gelesen, dieser wurde von der jetzt abgeschlossenen TA T2 geschrieben, deswegen muss T1 zurückgesetzt werden • als Serialisierungsreihenfolge ergibt sich daher T 2 < T 3, T1 kann nicht mit den anderen TAen serialisiert werden da ein (scheinbarer) Konflikt gefunden wurde Nachteile • TAen können wegen Scheinkonflikten zurückgesetzt werden, bei unseren Beispiel wurde T1 zurückgesetzt obwohl es den aktuellen Wert gelesen hatte • lange TAen können verhungern ==> ständiges Rollback wegen großen RS, das Schnittmenge mit WS kurzlaufender TAs hat • durch spätes Validieren ==> viel unnötige Arbeit beim Rücksetzen FOCC - forward oriented OCC • Validierung erfolgt gegenüber aktiven TAen • nur TAen die Daten ändern müssen validiert werden • validierende TA prüft, ob eine aktive TA ein Datum gelesen hat, das sie selbst geschrieben hat (Daten wurden geändert und andere TA hat nicht die aktuellen Daten gelesen) • Optionen für Konfliktlösung: 1. Kill (Rücksetzen der Konflikt TA(en) 2. Die (Rücksetzen der validierenden TA) Beispiel Für unser Beispiel ergibt sich bei FOCC folgendes: • T2: kann ohne Probleme validieren, da zu diesem Zeitpunkt keine TA ein Tupel gelesen hat was sie geschrieben hat • T3: hat zwar das Tupel y geschrieben aber die TA T2 ist bereits beendet und es findet keine Validierung gegen diese statt • T1: ist die letzte aktive TA somit muss keine Validierung stattfinden • als Serialisierungsreihenfolge ergibt sich daher T 2 < T 3 < T 1, es lassen sich hier also alle TAen serialisieren ohne das ein Konflikt auftritt Vorteile • Verhungern lässt sich über Kill-Ansatz steuern • nur echte Konflikte werden aufgelöst • Konfliktbewältigung lässt sich durch Wahl der Behandlung minimieren Aufgabe 2 Einbettung Datenbanksprachen (z. B. SQL) werden in höhere Programmiersprachen (z. B. Java, C++, teils gar COBOL, PL/1 oder Fortran, schröcklich) eingebettet. a) Erläutern Sie, warum eine solche Einbettung überhaupt vorgenommen wird. Lösung DB-Zugriffe aus APen heraus sind in der Praxis nichts ungewöhnliches, denn: • nacktes SQL“ ist dem Nutzer nicht zumutbar ==> braucht richtige“ APe ” ” •DB-Sprache allein ist nicht mächtig bzw. nicht komfortabel genug um richtige“ APe zu ” programmieren (Stichwort: Grafikausgabe) •höhere Prog.-Sprache allein ist nicht (bzw. nur sehr schlecht) für dauerhafte Ablage und Verwaltung von Daten geeignet (Stichwort: DBS vs. Dateisystem) (TAen,...) •==> Bei Anwendungsentwicklung: gemeinsame Nutzung von DBS-Sprache und höhere Programmiersprache •==> Einbettung einer DB-Sprache (z. B. SQL) in eine höhere Sprache (z. B. C++) b) Welche Probleme treten bei der Einbettung auf? Lösung •SQL und C++ sind verschiedene Sprachen. Mein Prog. soll Sprachelemente aus beiden Sprachen enthalten. Kombination“ nicht ganz so einfach ” •SQL ist deskriptiv, C++ hingegen prozedural ( WAS“ vs. WIE“) ” ” •SQL arbeitet mengenorientiert, C++ hingegen satzweise (Anfrage-Ergebnis kann beliebig ” groß“ sein, größe vorher nicht abschätzbar) •SQL und C++ nutzen verschiedene Datentypen •(impedance mismatch, spter mehr dazu) c) Welche prinzipiellen Ansätze für eine Programmierspracheneinbettung gibt es? Lösung Ansätze genauer Erklärt in Kopplungsarten von Programmiersprachen und Datenbanksprachen, Karl Neumann. Ausgeteilt während der Vorlesung. •Pre-Compiler-Ansatz ==> SQL-Anweisungen werden (mit einem speziellen Präfix gekennzeichnet) in den Quellcode eingesetzt. Ein Vorübersetzer erzeugt daraus, Quellcode ohe SQL-Anweisungen •Prozedurale Schnittstelle (=Call Level Interface) ==> DB-Funktionen werden über externe Prozeduren/Funktionen/Methoden aufgerufen (=DBMS Aufrufe). Z. B. Aufruf von SQLFetch(...) um nächstes Tupel zu holen; Beispiel Bibliotheken ODBC, JDBC, DB2CLI, SQL/CLI (Norm) •einfache Programmiersprachenerweiterung ==> Erweiterung der Programmiersprache um DB-Funktionen, jedoch keine Erweiterungen des Typsystems •komplexe Programmiersprachenerweiterung ==> wie einfache Erweiterung, jetzt aber mit Erweiterung des Typsystems, z. B. Tabelle als Datentyp •4-GL-Sprachen (Sprachen der 4. Generation) ==> echte“ Integration von Prog.-Sprachen ” und DB-Funktionalität d) Welchem dieser Ansätze ist ESQL zuzuordnen? Lösung ESQL gehört natürlich zu Pre-Compiler-Ansatz Aufgabe 3 ESQL Die Tabelle Kunde besitzt die Spalten KdNr, Name und Umsatz. In dieser Tabelle sind die Kundennummern, Namen und bisherigen Umsätze aller Kunden eines bekannten Unternehmens gespeichert, welches aus Geheimhaltungsgründen hier nicht genannt werden darf (nach wie vor militärisch-industrieller Komplex). Es soll nun ein Anwendungsprogramm entwickelt werden, das sich vom Benutzer einen Betrag eingeben lässt und dann alle Kunden (KdNr, Name und Umsatz) ausgibt, deren Umsatz den eingegebenen Betrag übersteigt (neudeutsch sog. Key Accounts“ also). ” a) Sollte für dieses Programm statisches oder dynamisches ESQL genutzt werden und warum? Lösung statisches ESQL, denn: •Die SELECT-Anweisung ist (bis auf Host-Variablen-Belegung in der WHERE-Klausel) bereits zum Vorübersetzungszeitpunkt vollständig bekannt •Dabei wird ausgenutzt, dass die Struktur des Anfrageergebnisses (Anzahl der Ergebnisspalten, Datentypen der Ergebnisspalten) zwangsläufig ebenfalls bekannt ist. •==> ich kann statisches ESQL benutzen. Wenn ich es kann, tue ich es auch, denn im Gegensatz zu dyn. ESQL, hier: •SQL-Anweisungen zum Vorübersetzungszeitpunkt prüfbar •leichter Programmierbar •bessere Performance (da Übersetzung + Optimierung der ESQL-Anweisung zum Vorübersetzungszeitpunkt) b) Muss in diesem Programm das Cursor-Konzept genutzt werden? Warum bzw. warum nicht? Lösung Ja, Cursorkonzept muss genutzt werden. Anfrageergebnis kann mehrere Tupel enthalten c) Skizzieren Sie die wesentlichen, datenbankrelevanten“ Teile des entsprechenden Programms. ” Sie können hierbei Pseudo-Code verwenden. Lösung EXEC SQL BEGIN DECLARE SECTION; /*Deklaration der HOSTvariablen, d.h. der gemeinsam genutzten Variablen*/ int betrag; int nummer; string name; int umsatz; EXEC SQL END DECLARE SECTION; /*Einbinden der SQL Communication Area (fuer Fehlermeldungen, Warnungen, etc.)*/ EXEC SQL INCLUDE SQLCA; lies Betrag in "betrag\ ein; EXEC SQL WHENEVER SQLERROR GOTO fehlerbehandlung; EXEC SQL DECLARE meincursor CURSOR FOR SELECT * FROM Kunde WHERE Unsatz > :betrag;/*Cursor an SELECT-Anweisung binden*/ EXEC SQL OPEN meincursor;/*SELECT Anweisung ausfuehren*/ /*Tupelweises Übertragen des Anfrageergebnisses while (SQLCA.SQLCODE == 0) EXEC SQL FETCH meincursor INTO :nummer, :name, :umsatz; Bildschirmausgabe von Nummer, Name und Umsatz; EXEC SQL CLOSE meincursor; fehlerbehandlung: Ausgabe ("Schade, Fehler\); END d) Beschreiben Sie die Funktion der ESQL-Anteile Ihres Programms. Lösung Enthalten im vorherigen Quellcode Aufgabe 4 Impedance Mismatch und Cursor Cursor spielen in SQL eine wichtige Rolle. Testen Sie Ihr Wissen anhand der folgenden Fragen. a) Was versteht man unter Impedance Mismatch? Lösung Impedance Mismatch = Fehlpassung“ zwischen deskriptiven (WAS) mengenorientiertem Da” tenzugriff in SQL und prozeduraler (WIE) satzweiser Verarbeitung in Programmiersprachen b) Was versteht man in diesem Zusammenhang unter einem Cursor? Beschreiben Sie das Wesentliche am Cursor-Konzept. Lösung DB-Cursor = spezielle Laufvariable zum Tupelweisen Abarbeiten des Anfrageergebnisses Cursorkonzept: •Ausführung der Anfrage und Übertragung des Anfrageergebnisses ins AP wird zeitlich getrennt •Das Anfrageergebnis wird Tupelweise ins AP übertragen c) An was (an welches Konstrukt) wird ein Cursor gebunden? Lösung Cursor wird an eine sQL-SELECT-Anweisung gebunden. (Also an eine Abfrage) d) Was passiert bei DECLARE CURSOR? Lösung DECLARE CURSOR: Cursor wird an SQL-SELECT-Anweisung gebunden e) Was passiert bei OPEN CURSOR? Lösung OPEN CURSOR: SQL-SELECT-Anweisung wird ausgeführt. Cursor wird vor das 1. Ergebnistupel positioniert f ) Was passiert bei FETCH? Lösung FETCH: Cursor wird um eine Position weiterbewegt. Dabei wird ein Ergebnistupel ins AP übertragen g) Wann wird die SELECT-Anweisung ausgeführt und wo steht der Cursor nach der Ausführung? Warum steht er da und wie lange? Lösung •Ausführung beim OPEN CURSOR •Cursor steht nach Ausführung vor dem 1. Tupel •weil: Anfrageergebnis könnte leer sein Wie lange steht er da? •bis er weiterbewegt wird (mittels FETCH) oder •bis er geschlossen wird (mittels CLOSE Tupelcursor) h) Wird bei ESQL stets ein Cursor benötigt? Lösung nein, •nicht falls keine SELECT-Anweisung (z. B. nur UPDATE, INSERT, DELETE) •nicht falls Anfrageergebnis garantiert nur 1 Tupel enthält (Beispielsweise Zugriff über Primärschlüssel) Aufgabe 5 UPDATE-Operation und Cursor Cursor spielen in SQL nicht nur beim lesenden Zugriff aufs Anfrageergebnis eine Rolle. Auch die SQL-UPDATE-Operation kann Bezug auf den Cursor nehmen. a) Wie nennt man diese Form des UPDATEs? Lösung positioniertes UPDATE b) Erläutern Sie diese Form des UPDATEs an einem kurzen Beispiel. Lösung EXEC SQL DECLARE Tupelcursor CURSOR FOR SELECT 2*A AS X FROM T FOR UPDATE OF A; EXEC SQL OPEN Tupelcursor EXEC SQL FETCH Tupelcursor INTO :hostVar; EXEC SQL UPDATE T SET A=1 WHERE CURRENT OF Tupelcursor; c) Können Sie diese Form des UPDATEs durch Eingabe von Ad-hoc-Anweisungen am Bildschirm testen? Lösung Ja. (funktioniert in DB2) d) Wie unterscheidet sich diese Form des UPDATEs vom gewöhnlichen“ UPDATE (also dem ” UPDATE ohne Bezugnahme auf den Cursor)? Lösung Unterscheidung in der Art und Weise“, wie die zu ändernden Tupel ausgewählt werden: ” keine Suchbedingung sondern bezugnahme auf aktuelle Cursorposition (Es wird nur 1 Tupel geändert) Bemerkung Zusätzliche Infos zum pos. UPDATE ,Dass beim positionierten UPDATE stets der ursprüngliche Spaltenname wird (und nicht der -Name der Ergebnisspalte) hat Konsequenzen“: ” ==>Beim positionierten UPDATE wird stets der Tabellenspaltenwert der Originaltabelle geändert und nicht der Tabellenspaltenwert im Anfrageergebnis EXEC SQL DECLARE Tupelcursor CURSOR FOR A X SELECT 2*A AS X 5 =>10 FROM T 4 8 FOR UPDATE OF A; 9 18 EXEC SQL OPEN Tupelcursor EXEC SQL FETCH Tupelcursor INTO :hostVar; A X EXEC SQL UPDATE T =>1 2 SET A=1 4 8 WHERE CURRENT OF Tupelcursor; 9 18 Also:Obwohl auf dem Anfrageergebnis gearbeitet wird, beziehen sich die Änderungen auf die Originaltabelle und nicht aufs Anfrageergebnis!!!