🔴 ACHTUNG: Dieser Modus ist für die meisten Anwendungen nicht geeignet – oft eine Quelle von Blocking, TempDB-Wachstum und schwer zu findenden Fehlern.
Normalerweise arbeitet SQL Server im
Autocommit-Modus: Jede einzelne INSERT-, UPDATE-, DELETE- oder SELECT INTO-Anweisung wird automatisch als eigene Transaktion ausgeführt und sofort committet.
Mit
SET IMPLICIT_TRANSACTIONS ON ändert sich das Verhalten drastisch: Die erste der folgenden Anweisungen startet eine Transaktion, die
explizit mit COMMIT oder ROLLBACK beendet werden muss:
- ALTER, INSERT, UPDATE, DELETE, DROP
- CREATE, SELECT (nur wenn SELECT INTO), FETCH, OPEN, REVOKE
- GRANT, TRUNCATE TABLE
SET IMPLICIT_TRANSACTIONS ON;
UPDATE Konto SET Saldo = Saldo - 100 WHERE Nr = 123;
SET IMPLICIT_TRANSACTIONS OFF;
💡 Wichtig: Im Gegensatz zu Oracle (wo ein explizites COMMIT nach jeder Transaktion nötig ist) ist dieses Verhalten in SQL Server weder üblich noch erwartet. Die meisten Entwickler kennen es nicht.
Die größte Gefahr: Entwickler, die den Modus nicht kennen, vergessen schlicht das abschließende COMMIT. Die Transaktion bleibt offen, hält Sperren auf betroffenen Tabellen (z. B. exklusive Sperren bei UPDATE) und blockiert andere Benutzer. Zudem wächst die tempdb (Versionstore) und der Transaktionslog wird nicht freigegeben.
SET IMPLICIT_TRANSACTIONS ON;
UPDATE Bestellungen SET Status = 'Versendet' WHERE Datum = '2025-01-01';
SELECT * FROM sys.dm_tran_active_transactions;
🚨 Typische Auswirkung: Anwendungen hängen, Deadlocks häufen sich, und der DBA muss manuell nach offenen Transaktionen suchen. In Produktivumgebungen kann dies einen kompletten Ausfall bedeuten.
Entwickler mit Oracle- oder PostgreSQL-Hintergrund sind gewohnt, dass sie explizit COMMITEN müssen. Aber in SQL Server ist
IMPLICIT_TRANSACTIONS ON nicht äquivalent zum Oracle‑Standard, denn:
- Eine Transaktion wird erst durch die erste DML gestartet – nicht beim Verbindungsaufbau.
- SELECT-Anweisungen (ohne INTO) starten keine Transaktion – das führt zu inkonsistentem Verhalten innerhalb eines Batches.
- Wenn eine Transaktion offen ist, muss sie immer mit COMMIT oder ROLLBACK beendet werden. Ein Verbindungstrennung ohne COMMIT rollt zurück – aber das ist nicht immer beabsichtigt.
❓ Fazit: Selbst wer bewusst Transaktionen steuern möchte, sollte explizites BEGIN TRAN verwenden. Das ist klarer, besser lesbar und nicht von einer Session-Einstellung abhängig.
Im normalen Autocommit-Modus werden Sperren nach jeder Anweisung freigegeben. Bei IMPLICIT_TRANSACTIONS ON kann eine einzelne lange Transaktion – beispielsweise durch einen Batch mit vielen Updates – die Sperren über die gesamte Dauer halten. Das erhöht die Wahrscheinlichkeit von Blocking und Deadlocks drastisch. Auch das Transaktionslog wird erst beim COMMIT freigegeben, was bei großen Änderungen zu unerwartetem Wachstum führt.
SET IMPLICIT_TRANSACTIONS ON;
DECLARE @i INT = 1;
WHILE @i <= 10000
BEGIN
UPDATE GrossTabelle SET Wert = Wert + 1 WHERE Id = @i;
SET @i = @i + 1;
END;
COMMIT;
⚡ Besser: Entweder Autocommit nutzen oder eine explizite Transaktion mit regelmäßigen COMMIT in Batches aufteilen.
Innerhalb einer gespeicherten Prozedur kann der Entwickler leicht übersehen, dass der implizite Modus aktiv ist. Fehlerbehandlung mit IF @@TRANCOUNT > 0 ROLLBACK wird dann zwar funktionieren, aber ohne expliziten Start der Transaktion ist die Logik schwer nachvollziehbar. Zudem kann ein früheres COMMIT im Batch den Zustand unerwartet ändern.
CREATE PROCEDURE dbo.UpdateData
AS
BEGIN
SET IMPLICIT_TRANSACTIONS ON;
UPDATE ... ;
IF (@@ERROR <> 0) ROLLBACK; ELSE COMMIT;
END
📌 Empfehlung: Verlassen Sie sich niemals auf session‑weite Einstellungen für Transaktionssteuerung. Verwenden Sie stattdessen BEGIN TRAN/COMMIT explizit – das ist selbst-dokumentierend und funktioniert unabhängig von Client-Einstellungen.
Moderne ORMs gehen vom Autocommit-Modus aus. Wenn Sie IMPLICIT_TRANSACTIONS ON auf der Verbindung einschalten, kann dies zu unerwartet langen Transaktionen führen, da das ORM vielleicht kein abschließendes COMMIT sendet (weil es denkt, es wäre im Autocommit). Die Folge: Transaktionen bleiben offen, bis die Verbindung geschlossen wird – was zu veralteten Sperren und schlechter Skalierbarkeit führt.
🔥 Bekannte Fallstricke: Insbesondere wenn Verbindungspooling aktiv ist, kann eine offene Transaktion bei einer zurückgegebenen Verbindung bestehen bleiben und die nächste Operation blockieren.
Die Lösung ist einfach: Nutzen Sie für atomare Einheiten explizite Transaktionen mit BEGIN TRAN und COMMIT/ROLLBACK. Für alles andere bleibt der Standard-Autocommit-Modus (der hervorragend funktioniert).
BEGIN TRANSACTION;
INSERT INTO Log (Message) VALUES ('Änderung beginnt');
UPDATE Konten SET Saldo = Saldo - 50 WHERE Id = 1;
UPDATE Konten SET Saldo = Saldo + 50 WHERE Id = 2;
COMMIT TRANSACTION;
🎯 Fazit: Verzichten Sie generell auf SET IMPLICIT_TRANSACTIONS ON. Die wenigen Szenarien, in denen es könnte als Abkürzung dienen (z. B. Migration von Oracle-Code) sind durch eine saubere Übersetzung besser gelöst. Der implizite Modus ist eine Quelle von Fehlern, die schwer zu debuggen sind.
Prüfen Sie, ob eine Session den impliziten Modus verwendet:
SELECT session_id, CASE WHEN is_implicit_transaction = 1 THEN 'ON' ELSE 'OFF' END AS ImplicitMode
FROM sys.dm_exec_sessions
WHERE is_user_process = 1;
🛠️ Gegenmaßnahme: Setzen Sie in Anwendungsverbindungen explizit SET IMPLICIT_TRANSACTIONS OFF (das ist auch der Standard). Entfernen Sie alle unsichtbaren Aktivierungen in gespeicherten Prozeduren oder Triggern.