单个 sqlconnection 中的多个 sqltransactions

发布于 2024-09-16 10:48:40 字数 983 浏览 1 评论 0原文

我有一些想要执行的代码,如下所示。但我在第二次迭代时不断收到异常“此 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();
      }

I have some code that I want to execute as follows. But I keep getting the exception "This SqlTransaction has completed; it is no longer usable" on the 2nd iteration. Could someone help me point out what I am doing wrong here? Thanks!

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

划一舟意中人 2024-09-23 10:48:41

在循环内,您可以提交或回滚,但不会将引用重置为 nullSqlTransaction 通常不这样使用,而是在 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);
  }
}

Inside the loop you either commit or rollback, but you do not reset the reference to null. SqlTransaction in general is not used as this, is used in a using() block, just as a SqlConnection is:

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);
  }
}
写下不归期 2024-09-23 10:48:41

尝试在处置后将 sqlTransaction 对象设置为 null。旁注,您确实应该将这些 IDisposable 对象包装在 using 块中,以便始终调用 Dispose

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

Try setting your sqlTransaction object to null after disposing it. Side note, you really should be wrapping those IDisposable objects in using blocks so Dispose is called at all times.

sqlTransaction.Commit();
sqlTransaction.Dispose();
sqlTransaction = null;
梦初启 2024-09-23 10:48:41

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

You need to create a new SqlTransaction object on each iteration or move the transaction completely outside the loop if you are wanting all the operations inside the loop to occur in a single transaction. Once you commit a transaction, it is necessary to call BeginTransaction again on the connection to start a new one. You cannot reuse the old transaction object.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文