mehrere sqltransactions in einzelnen SQLConnection
-
01-10-2019 - |
Frage
ich einen Code haben, dass ich wie folgt ausgeführt werden soll. Aber ich erhalte immer die Ausnahme „Das SqlTransaction abgeschlossen, es ist nicht mehr verwendbar“ auf der zweiten Iteration. Könnte mir jemand helfen darauf hinweisen, was ich hier falsch mache? Dank!
SqlConnection cn = (SqlConnection)SqlConnectionManager.Instance.GetUserConnection(user);
cn.Open();
try
{
foreach (Master mRecord in masterList)
{
if (sqlTransaction == null)
sqlTransaction = cn.BeginTransaction();
SqlCommand cm = cn.CreateCommand();
cm.Transaction = sqlTransaction;
cm.CommandType = CommandType.StoredProcedure;
cm.CommandText = "pr_InsertRecords";
try
{
cm.ExecuteNonQuery();
Debug.WriteLine("Auditor.Write: end sql table value param");
sqlTransaction.Commit();
sqlTransaction.Dispose();
}
catch (Exception Ex)
{
Debug.WriteLine(" Exception message: " + Ex.Message);
if (Ex.InnerException != null)
{
Debug.WriteLine("Inner exception message" + Ex.InnerException.Message);
}
sqlTransaction.Rollback();
}
}
}
finally
{
cn.Close();
}
Lösung
Innerhalb der Schleife Sie entweder Commit oder Rollback, aber Sie nicht zurückgesetzt den Verweis auf null
. SqlTransaction
im Allgemeinen nicht als diese verwendet wird, wird in einem using()
Block verwendet, ebenso wie ein SqlConnection
ist:
using (SqlConnection cn = SqlConnectionManager.Instance.GetUserConnection(user))
{
foreach (Master mRecord in masterList)
{
try
{
using (SqlTransaction sqlTransaction = cn.BeginTransaction())
{
using (SqlCommand cm = cn.CreateCommand())
{
cm.Transaction = sqlTransaction;
cm.CommandType = CommandType.StoredProcedure;
cm.CommandText = "pr_InsertRecords";
cm.ExecuteNonQuery();
}
sqlTransaction.Commit();
Debug.WriteLine("Auditor.Write: end sql table value param");
}
}
catch (Exception Ex)
{
Debug.WriteLine(" Exception message: " + Ex.Message);
}
}
Andere Tipps
Versuchen Sie sqlTransaction
Objekt auf null einstellen, nachdem sie zu entsorgen. Randnotiz, sollten Sie wirklich diese IDisposable
Objekte in Verwendung von Blöcken werden Einwickeln so Dispose
jederzeit aufgerufen wird.
sqlTransaction.Commit();
sqlTransaction.Dispose();
sqlTransaction = null;
Sie müssen ein neues SqlTransaction
Objekt bei jeder Iteration erstellen oder die Transaktion vollständig außerhalb der Schleife bewegen, wenn Sie alle Vorgänge innerhalb der Schleife fehlen in einer einzigen Transaktion auftreten. Sobald Sie eine Transaktion zu begehen, ist es notwendig, Begintrans wieder auf die Verbindung zu nennen, eine neue zu starten. Sie können nicht das alte Transaktionsobjekt wiederverwendet werden.