Sonntag, 24. März 2013

Transaktionen SAVEPOINT

Arbeitet man in einer Transaktion und möchte im Fehlerfall nicht die komplette Transaktion sondern nur einen speziellen Code-Abschnitt zurückspielen, so kann man mit sogenannten Savepoints arbeiten.

Von diesen Haltepunkten kann man beliebig viele setzen.
Auch hier ist es wieder ratsam einen Namen pro Savepoint zu vergeben, um diesen später gezielt anzusprechen.

Einen Savepoint setzt man wie folgt:

-- Savepoint setzen 
SAVE TRANSACTION sp1


Um von der aktuellen (Verarbeitungs-)Position in der Transaktion alles bis zu einem Savepoint zurückzusetzen muss man das ROLLBACK wie folgt aufrufen, wobei sp1 der Name des Savepoints ist.


-- Zurückspielen der Transaktion bis zum angegebene Savepoint
ROLLBACK TRANSACTION sp1


Beispiel:


INSERT INTO Farben
VALUES('rot')

SAVE TRANSACTION sp1

INSERT INTO Farben
VALUES('blau')

-- Rollback bis zum Savepoint sp1 durchführen
-- Die Farbe "blau" wird entfernt
-- Die Farbe "rot bleibt weiterhin bestehen
ROLLBACK TRANSACTION sp1

-- Die gesamte Transaktion wird zurückgeschrieben
-- Die Farbe "blau" wird entfernt
-- Die Farbe "rot wird entfernt
ROLLBACK TRANSACTION


Hinweis:
Hier unterscheidet sich die Verarbeitung zwischen Oracle und MSSQL-Server.
Beim MSSQL-Server wird der Savepoint bei einen Rollback mit verworfen.
Bei Oracle hingegen bleibt dieser bestehen.


Außerdem unterscheidet sich die Syntax bei Oracle wie folgt:


-- Savepoint setzen 
SAVEPOINT sp1

-- Rollback bis zum Savepoint
ROLLBACK TO SAVEPOINT sp1

Mittwoch, 20. März 2013

Benannte Transaktionen

Bei der Verwendung von mehreren Transaktionen in einem Skript, ist es übersichtlicher wenn man die einzelnen Transaktionen benennt.

Dieses kann man einfach machen, indem man einen beliebigen Namen hinter das TRANSACTION hängt.
Es ist dabei wichtig, dass man den Namen im weiteren Verlauf wie z.B. beim COMMIT oder ROLLBACK immer angibt.

Beispiel:

BEGIN TRANSACTION BeispielTransaktion;
ROLLBACK TRANSACTION BeispielTransaktion;
COMMIT TRANSACTION BeispielTransaktion;

Dienstag, 19. März 2013

TRANSACTION! COMMIT? ROLLBACK?

Oft sieht mit in SQL-Skripten, die mit Transaktionen arbeiten folgende oder ähnliche Abfrage:

-- Transaktion rückgängig machen
IF @@TRANCOUNT > 0
    ROLLBACK TRANSACTION; 

Aber was genau steckt eigentlich dahinter?
Eigentlich ist diese Abfrage mehr oder weniger Quatsch bzw. falsch.

Die globale Variable @@TRANCOUNT gibt nur die Anzahl der mit "BEGIN TRANSACTION" geöffneten Transaktionen zurück.
Das heißt, an dieser Stelle wird geprüft, ob es eine offene Transaktion gibt. Wenn dieses der Fall ist, dann wird eine (die zuletzt geöffnete) geschlossen.

An dieser Stelle weiß man jedoch nicht, ob die Transaktion erfolgreich oder fehlerhaft war.
Also könnte man auch nicht sagen, ob diese bestätigt (commit) oder zurückgeschrieben (rollback) werden sollen.
Diese Information bekommt man aber ganz einfach direkt über eine SQL-Server-Funktion.

Über die Systemfunktion XACT_STATE() kann der aktuelle Transaktionsstatus manuell geprüft werden.
Mögliche Rückgabewerte sind folgende:
# 1 => Es ist eine Transaktion vorhanden, die korrekt verarbeitet wurde und committed werden kann.
# 0 => Es ist keine Transaktion vorhanden.
# -1 => Es ist eine Transaktion vorhanden, die aber fehlerhaft verarbeitet wurde und nicht committed werden kann. Diese Transaktion kann nur noch vollständig per ROLLBACK zurückgeschrieben werden.

Anhand dieser Funktion kann man also die Transaktion bzw. dessen Status prüfen und diese bestätigen oder zurückschreiben.

Möchte man die Transaktion nicht manuell zurückschreiben, dann könnte man dieses auch automatisch vom SQL-Server machen lassen. In diesem Fall gilt nur zu beachten, dass die Transaktion trotzdem bei erfolg bestätigt werden muss.

XACT_ABORT(ON/OFF) ist eine Eigenschaft die über SET beliebig eingestellt werden kann.
Diese Eigenschaft gibt an ob eine fehlgeschlagene Transaktion automatisch zurückgeschrieben werden soll.

Dienstag, 12. März 2013

Einfaches Arbeiten mit Transaktionen


Eine Transaktion bezeichnet eine Gruppe von Datenbankabfragen, welche nur gemeinsam ausgeführt werden können.

Dieses ist in ganz unterschiedlichen Bereichen wie z.B. in der Lagerlogistik bei einer Lagerumbuchung notwendig.
Wird ein Artikel von einem Lagerplatz auf einen anderen verschoben, so darf zwischen der Entnahme- und der Ziel-Buchung keine Möglichkeit für Eingriffe bestehen.
Ansonsten könnte es zu Problemen kommen und ein Artikel könnte doppelt verbucht werden.

Einfach gesagt, bündeln Transaktionen also nur mehrere SQL-Abfragen.
Eine Transaktion muss immer geöffnet und auch wieder geschlossen werden.

Öffnen kann man eine Transaktion so:
 -- Transaktion starten
 BEGIN TRANSACTION;

Ist eine Transaktion offen, können diverse SQL-Abfragen durchgeführt werden.
Gibt es hierbei keine Fehler, so kann man die Transaktion einfach wie folgt schließen.

-- Transaktion schließen/bestätigen
COMMIT TRANSACTION;

 Erst mit einem COMMIT werden die ausgeführten Abfragen in der Datenbank veröffentlicht.

Gibt es bei der Verarbeitung der beinhalteten SQL-Abfragen Probleme/Fehler, so muss die Transaktion manuell oder automatisch zurückgeschrieben werden. Dabei werden alle durchgeführten Abfragen verworfen.

Das zurückschreiben kann wie folgt durchgeführt werden.

 -- Transaktion rückgängig machen
 ROLLBACK TRANSACTION;

Montag, 11. März 2013

Grundlegende Änderung in diesem Blog

Wer mich kennt, weiß dass ich ursprünglich aus der Microsoft SQL-Server Administration komme.
In den letzten Jahren habe ich diesen Bereich etwas vernachlässigt.
Da mir die Verwaltung sowie die Entwicklung mit dem SQL-Server aber immer (naja eher oft ;-)) sehr viel Freude bereitet hat, möchte ich wenigstens weiterhin darüber bloggen.

Da ich aktuell nur noch wenig gute und vor allem wirklich aktive Blogs zum Thema SQL-Server kenne, möchte ich diesen Blog wieder aktiver nutzen und vor allem das grundlegende Thema ändern.

Es kann zwar durchaus passieren, dass noch einmal ein Post zum Thema .Net/C# rausrutscht.
Das Hauptthema dieses Blogs soll aber zukünftig der Microsoft SQL-Server werden.

Hier möchte ich die Gelegenheit nutzen und noch einmal grundlegende Themen aufarbeiten um spätere Posts auch darauf aufzubauen.