Вопрос

У меня есть какой-код, который я хочу выполнить следующим образом. Но я продолжаю получать исключение «Это SQLTransaction завершило; это больше не используется» на 2 итерации. Может кто-нибудь помочь мне указать, что я здесь не так? Спасибо!

    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();
      }
Это было полезно?

Решение

Внутри петли вы либо совершаете, либо откат, но вы не сбрасываете ссылку на null. SqlTransaction В целом не используется как это, используется в using() блок, как SqlConnection является:

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);
  }
}

Другие советы

Попробуйте установить ваш sqlTransaction объект к нулю после утилизации. Сторона, вы действительно должны упасть те IDisposable объекты в использовании блоков так Dispose называется во все времена.

sqlTransaction.Commit();
sqlTransaction.Dispose();
sqlTransaction = null;

Вам нужно создать новый SqlTransaction Объект на каждой итерации или полностью переместите транзакцию за пределами петли, если вы хотите, чтобы все операции внутри цикла произошли в одной транзакции. Как только вы совершаете транзакцию, необходимо снова позвонить за мочеиспускание на связи, чтобы начать новый. Вы не можете повторно использовать старый объект транзакции.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top