Transaktion (Transaction): Eine Gruppe von SQL‑Befehlen, die atomar ausgeführt werden. Entweder werden alle Änderungen per (Commit) übernommen oder bei Fehlern vollständig rückgängig gemacht (Rollback). Es erfüllt die ACID‑Eigenschaften.
In .NET Framework/.NET wird dafür SqlTransaction (nur für SQL‑Server) verwendet.
Wichtige Ablaufpunkte:
- Datenbankverbindung öffnen
conn.Open()- Transaktion über die Verbindung starten
conn.BeginTransaction()- Das Transaktionsobjekt an
SqlCommand.Transactionzuweisen- Mehrere SQL‑Anweisungen stapelweise ausführen
- Keine Ausnahme:
tx.Commit();Ausnahme abfangen:tx.Rollback()
Beispiel
Der ursprüngliche Code enthält keine catch‑Rückgängig‑Logik. Hier die vollständige lauffähige Fassung:
public static int ExecuteSqlTran(List<string> SQLStringList)
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
SqlTransaction tx = conn.BeginTransaction();
cmd.Transaction = tx;
try
{
int count = 0;
for (int n = 0; n < SQLStringList.Count; n++)
{
string strsql = SQLStringList[n];
if (strsql.Trim().Length > 1)
{
cmd.CommandText = strsql;
count += cmd.ExecuteNonQuery();
}
}
tx.Commit(); // Bei Erfolg alle Änderungen übernehmen
return count;
}
catch (Exception ex)
{
tx.Rollback(); // Bei beliebigem Fehler alles rückgängig machen
throw ex; // Ausnahme weiterwerfen, damit obere Schicht den Fehler erkennt
}
}
}Code-Sprache: C# (cs)
Diese Variante fügt SQL‑Zeichenketten direkt zusammen und birgt ein SQL‑Injektionsrisiko. Sie eignet sich zum Verständnis von Transaktionen. In Produktivprojekten sollten Sie parametrisierte Abfragen bevorzugen.
Transaktionsbeispiel mit Parametrisierung
Schleifen‑Einfügung mit SqlParameter zum Schutz vor Injektionen. Wichtige Hinweise:
- Am Ende jeder Schleifeniteration
sqlCom.Parameters.Clear()aufrufen, um alte Parameter zu entfernen und Überlauf‑Fehler zu vermeiden - Dieselbe
SqlCommand‑Instanz wiederverwenden, nur CommandText und Parameter aktualisieren
SqlCommand sqlCom = new SqlCommand();
sqlCom.Connection = conn;
SqlTransaction st = conn.BeginTransaction();
sqlCom.Transaction = st;
int res = 0;
try
{
for (int i = 0; i < 10; i++)
{
sqlCom.CommandText = "INSERT INTO [dbo].[Article]([Title])VALUES(@Title)";
SqlParameter param = new SqlParameter("@Title", SqlDbType.NVarChar, 250);
param.Value = i + "Neuer Titel" + DateTime.Now;
sqlCom.Parameters.Add(param);
res += sqlCom.ExecuteNonQuery();
sqlCom.Parameters.Clear(); // Parameter für nächsten Durchlauf löschen
}
st.Commit();
}
catch (Exception)
{
st.Rollback(); // Bei Ausnahme alle Änderungen rückgängig machen
}Code-Sprache: C# (cs)
1. Zwingend einzuhaltende Regeln
BeginTransaction()muss nach dem Verbindungs‑Aufruf Open ausgeführt werden- Bei
SqlCommandmuss die EigenschaftTransactiongesetzt werden, sonst wird eine Ausnahme ausgelöst - Nach
Commit()/Rollback()endet die Transaktion automatisch, wiederholte Aufrufe sind unzulässig
Sonstiges
- Unter .NET Core/.NET 5+ empfiehlt sich die
using‑Anweisung zur automatischen Freigabe vonSqlTransaction - Bei sehr großen SQL‑Stapeln kommt
SqlBulkCopyin Frage; es ist schneller als wiederholtes ExecuteNonQuery in Schleifen SqlTransactionunterstützt keine datenbankübergreifenden Transaktionen, verwenden Sie verteilte Transaktionen mitTransactionScope
SqlTransaction Datenbank‑Transaktionen