单个sqlconnection中的多个sqltransactions

时间:2010-08-24 19:30:15

标签: c# database sqlconnection sqltransaction

我有一些代码要执行,如下所示。但是我继续在第二次迭代中得到异常“这个SqlTransaction已经完成;它不再可用”。有人能帮助我指出我在这里做错了吗?谢谢!

    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 个答案:

答案 0 :(得分:4)

在循环内部,您可以提交或回滚,但不会将引用重置为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);
  }
}

答案 1 :(得分:2)

如果您希望循环内的所有操作都在单个事务中发生,则需要在每次迭代时创建一个新的SqlTransaction对象,或者将事务完全移出循环。提交事务后,必须再次在连接上调用BeginTransaction以启动新事务。您无法重用旧的事务对象。

答案 2 :(得分:2)

处理后,请尝试将sqlTransaction对象设置为null。请注意,您确实应该使用块来包装这些IDisposable个对象,以便始终调用Dispose

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