2014-10-16 4 views
0

내 SQL 명령에 의해 실행 된 3 delete 개의 쿼리가 있습니다. 세 개의 쿼리 중 마지막 쿼리는 다른 테이블에 대한 참조가없는 경우에만 실행할 수 있습니다. 참조가 있으면 실행되지 않습니다. 따라서 마지막 삭제가 실패한 경우 이전의 2 개 명령에서 삭제 된 데이터가 손실되지 않도록 rollback을 원합니다. 이것이 내가 SqlTransaction을 사용해야하는 이유입니다.SQL 트랜잭션 항상 걸림

다음은 내가 생각해 낼 수 있었던 것입니다. 실제로 데이터 손실을 막을 수는 있지만 아무 것도 지울 수 없으며 항상 팝업이 표시됩니다 (실행될 때마다 의미가 잡히는).

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

아무것도하지만, 혹시 이상한 .. 콘솔에 쓴 :

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

} 

는 또한, 내가 사용하여 문제를 찾으려고?

SqlTransaction을 실행하는 적절한 방법입니까? 나는 이렇게하기 위해 a guide from the microsoft site을 따라 갔다. 왜 항상 잡히는거야?

감사합니다.

+1

해피'try' 블록에서 연결을 닫기 전에 SqlTransaction을 커밋해야합니다. 예외 (또는 InnerException)가이를 언급해야합니다. – StuartLC

+2

또한'sqlCommand.Transaction'을'sqlTran'으로 설정해야한다고 생각합니다. – juharr

+0

@StuartLC 대단한 관찰! 나는 저 지르지 않았다. 그러나'MyCommand.ExecuteNonQuery(); '바로 뒤에'sqlTran.Commit();을 삽입해도 문제가 해결되지 않습니다 – starvator

답변

2

sqlTran.Commit(); 트랜잭션을 커밋해야합니다. @juharr이

+0

위대한 관찰! 나는 저 지르지 않았다. 그러나'MyCommand.ExecuteNonQuery();'바로 뒤에'sqlTran.Commit();'을 두어도 문제가 해결되지 않습니다 – starvator

+0

그리고 예외는 없습니까? – brz

+0

@juharr이 지적했듯이 나머지 문제는 MyCommand.Transaction = sqlTran;을 설정해야한다는 것입니다. – starvator

1

을 지적

는 또한 문제가 커밋 명령에 대한 트랜잭션을 설정 누락 된 거래입니다 MyCommand.Transaction = sqlTran;을 설정합니다. 다음은 명시 적으로 Rollback 또는 Close을 호출 할 필요없이 트랜잭션이 롤백되고 예외가 발생했을 때 연결이 닫히도록하는 connect, transaction 및 command에 대한 using 문을 사용하여 수행하는 방법입니다. 명령을 실행 한 후에 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(); 
      } 
     } 
    } 
}