Weiter Zurück Inhalt

6. Transaktionen

Will Kunde A an Kunde B Geld überweisen, so sind 2 Buchungen nötig. Schlecht wäre es, wenn es zwischen den beiden Buchungen zu einem Stromausfall käme. Dafür verwenden wir also eine Transaktion, um diese beiden Buchungen in einer Einheit durchzuführen.

Wir schreiben einfach eine Funktion in der Sprache SQL. Alles innerhalb einer Funktion ist automatisch auch innerhalb einer Transaktion.

001 --
002 -- Funktion, um automatisiert eine Buchung zu erstellen
003 --
004 
005 CREATE OR REPLACE FUNCTION transfer(von INT, nach INT, NUMERIC(10,2), TEXT varchar) RETURNS bool AS '
006         -- Abbuchung bei Kunde 1 auslösen
007         INSERT INTO buchungen (kontonr, ts, typ, wert, text) VALUES ($1, NOW(), ''A'', $3, $4);
008         -- den Betrag bei Kunde 2 auf das Konto buchen
009         INSERT INTO buchungen (kontonr, ts, typ, wert, text) VALUES ($2, NOW(), ''Z'', $3, $4);
010         -- einen Rückgabewert für OK liefern
011         SELECT true;
012 ' LANGUAGE sql;
013 
014 
015 -- Tests
016 
017 -- theoretisch haben wir kein Geld auf der Bank, da bisher kein Kunde
018 -- Geld erhalten hat. Jedoch haben einige Kunden einen Dispo erhalten
019 -- und können somit ihr Konto belasten
020 SELECT transfer ( (SELECT kontonr::INTEGER FROM kunden WHERE kundenname='Kunde 1'),
021                   (SELECT kontonr::INTEGER FROM kunden WHERE kundenname='Kunde 2'),
022                   100.00,
023                   'Überweisung Nr. 1, Kunde 1 an Kunde 2');
024 
025 -- Kontoübersicht anschauen
026 SELECT * FROM saldeninfo( (SELECT kontonr::INTEGER FROM kunden WHERE kundenname='Kunde 1') );
027 SELECT * FROM saldeninfo( (SELECT kontonr::INTEGER FROM kunden WHERE kundenname='Kunde 2') );
028 
029 -- Geld zurückschicken
030 SELECT transfer ( (SELECT kontonr::INTEGER FROM kunden WHERE kundenname='Kunde 2'),
031                   (SELECT kontonr::INTEGER FROM kunden WHERE kundenname='Kunde 1'),
032                   100.00,
033                   'Überweisung Nr. 2, Kunde 2 an Kunde 1');
034 
035 -- Kontoübersicht anschauen
036 SELECT * FROM saldeninfo( (SELECT kontonr::INTEGER FROM kunden WHERE kundenname='Kunde 1') );
037 SELECT * FROM saldeninfo( (SELECT kontonr::INTEGER FROM kunden WHERE kundenname='Kunde 2') );
038 
039 -- das Finanzamt sieht nur die Buchungen
040 SELECT * FROM view_buchungen;
041 
042 -- versuchen wir, einmal den Dispo zu überziehen
043 SELECT transfer ( (SELECT kontonr::INTEGER FROM kunden WHERE kundenname='Kunde 5'),
044                   (SELECT kontonr::INTEGER FROM kunden WHERE kundenname='Kunde 4'),
045                   300.00,
046                   'Überweisung Nr. 3, Kunde 5 an Kunde 4');
047 SELECT * FROM saldeninfo( (SELECT kontonr::INTEGER FROM kunden WHERE kundenname='Kunde 5') );
048 SELECT * FROM saldeninfo( (SELECT kontonr::INTEGER FROM kunden WHERE kundenname='Kunde 4') );
Download transfer.sql

Was passiert, wenn wir erst bei B das Geld einzahlen, und dann erst bei A abziehen, und bei A kommt es zu einer Überziehung des Kontos? Nun, probieren wir es aus!


Weiter Zurück Inhalt