2014-10-16 50 views
0

我有3 delete由我的sql命令执行的查询。如果在其他表中没有引用它,则只能执行三个查询中的最后一个。如果有参考,它将无法执行。所以,如果最后一次删除失败,我想rollback不会丢失前两个命令中将要删除的数据。这就是为什么我需要使用SqlTransactionSQL事务总是被捕获

以下是我能够想到的。它实际上可以防止丢失任何数据,但是,我无法删除任何内容,并且总是得到弹出窗口(意味着每次执行它时都会被捕获)。

protected void editDelete(object sender, DirectEventArgs e) 
{ 
    SqlConnection MyConnection = new SqlConnection(); 
    MyConnection.ConnectionString = ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString; 

    MyConnection.Open(); 

    // Start a local transaction. 
    SqlTransaction sqlTran = MyConnection.BeginTransaction(); 

    try 
    { 
     SqlCommand MyCommand = new SqlCommand(); 
     MyCommand.CommandText = /* 3 queries removed to shorten code */; 
     MyCommand.CommandType = CommandType.Text; 
     MyCommand.Connection = MyConnection; 

     SqlParameter p1 = new SqlParameter("@id", this.accountidEdit.Value); 
     MyCommand.Parameters.Add(p1); 

     MyCommand.ExecuteNonQuery(); 
     MyConnection.Close(); 


     /* reload and notification calls removed to shorten code */ 
    } 
    catch (Exception) 
    { 
     sqlTran.Rollback(); 
     X.Msg.Alert("Error", "Error.").Show(); 
    } 

} 

此外,我试图通过查找问题:

catch (Exception sqlexception) 
    { 
     Console.WriteLine(sqlexception.Message); 
     sqlTran.Rollback(); 
     X.Msg.Alert("Error", "Error.").Show(); 
    } 

但没有写过控制台..怪异?

这是执行SqlTransaction的正确方法吗?我跟着a guide from the microsoft site来做到这一点。为什么它总是被抓到?

谢谢!

+1

您需要在快乐'try'块中关闭连接之前提交SqlTransaction。异常(或InnerException)应该提及这一点。 – StuartLC 2014-10-16 15:20:31

+2

此外,我认为你需要将'SqlCommand.Transaction'设置为'sqlTran'。 – juharr 2014-10-16 15:22:14

+0

@StuartLC伟大的观察!我没有提交。然而,在'MyCommand.ExecuteNonQuery();'之后直接放置'sqlTran.Commit();'并不能解决问题 – starvator 2014-10-16 15:22:22

回答

2

您必须提交交易sqlTran.Commit();

此外,设置MyCommand.Transaction = sqlTran;为@juharr指出

+0

伟大的观察!我没有提交。但是,在'MyCommand.ExecuteNonQuery();'后面直接放置'sqlTran.Commit();'并不能解决问题 – starvator 2014-10-16 15:20:44

+0

并且没有例外? – brz 2014-10-16 15:22:16

+0

剩下的问题,正如@juharr指出的那样,我还需要设置'MyCommand.Transaction = sqlTran;' – starvator 2014-10-16 15:25:27

1

的问题是缺少事务提交并设置该命令的交易。以下是我将如何使用连接,事务和命令的using语句执行此操作,以确保事务回滚并在异常情况下关闭连接,而无需明确呼叫RollbackClose。必须在执行该命令后调用Commit。通过从连接创建命令,您不必设置连接,但我认为您仍然必须设置事务。如果你不需要显示弹出框的try-catch,这可以进一步模拟。

protected void editDelete(object sender, DirectEventArgs e) 
{ 
    using (
     var MyConnection = 
      new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString)) 
    { 
     MyConnection.Open(); 

     // Start a local transaction. 
     using (var sqlTran = MyConnection.BeginTransaction()) 
     { 
      try 
      { 
       using(var MyCommand = MyConnection.CreateCommand()) 
       { 
        MyCommand.CommandText = /* 3 queries removed to shorten code */; 
        MyCommand.CommandType = CommandType.Text; 
        MyCommand.Transaction = sqlTran; 
        SqlParameter p1 = new SqlParameter("@id", this.accountidEdit.Value); 
        MyCommand.Parameters.Add(p1); 

        MyCommand.ExecuteNonQuery(); 
        sqlTran.Commit(); 
       } 


       /* reload and notification calls removed to shorten code */ 
      } 
      catch (Exception) 
      { 
       X.Msg.Alert("Error", "Error.").Show(); 
      } 
     } 
    } 
}