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();
      }
War es hilfreich?

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top