несколько sqltransaction в одном sqlconnection - PullRequest
2 голосов
/ 24 августа 2010

У меня есть код, который я хочу выполнить следующим образом.Но я продолжаю получать исключение «Эта 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();
      }

Ответы [ 3 ]

4 голосов
/ 24 августа 2010

Внутри цикла вы либо фиксируете, либо выполняете откат, но вы не сбрасываете ссылку на 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);
  }
}
2 голосов
/ 24 августа 2010

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

sqlTransaction.Commit();
sqlTransaction.Dispose();
sqlTransaction = null;
2 голосов
/ 24 августа 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...