2015-01-09 7 views
0

Давайте предположим, что мы имеем объект А, который может быть удален в объект B, который провести forendkey от AКак я использовать SqlTransaction через методы кратной

Если вы хотите удален А, вы должны удалить forendkey из B сначала, а затем вы можете удалить A, но если что-то пойдет не так, его нужно отбросить, но я также хочу использовать delete forendkey от B независимо, но на данный момент я не знаю, как достичь этого

моя текущая идея:

public void DeleteA(Object a) 
    { 
     using (SqlConnection con = new SqlConnection()) 
     { 
      con.open(); 

      using (SqlTransaction tr = con.BeginTransaction()) 
      { 
       try 
       { 
        DeleteAfromAllB(a, con, tr); 

        using (SqlCommand cmd = new SqlCommand("STP_A_Delete", con)) 
        { 
         cmd.Transaction = tr; 

         // some parameters 
         // some sort of Execute 
         // e.g.: cmd.ExecuteNonQuery(); 
        } 
        tr.Commit(); 
       } 
       catch (SqlException ex) 
       { 
        //ExceptionHandling 
       } 
      } 
     } 
    } 

    private void DeleteAfromAllB(Object a, SqlConnection con, SqlTransaction tr) 
    { 
     try 
     { 
      using (SqlCommand cmd = new SqlCommand("STP_B_Delete_Referenc_To_A", con)) 
      { 
       cmd.Transaction = tr; 

       // some parameters 
       // some sort of Execute 
       // e.g.: cmd.ExecuteNonQuery(); 
      } 
     } 
     catch (SqlException ex) 
     { 
      //ExceptionHandling 
     } 
    }  

    public void DeleteAfromAllB(Object a) 
    { 
     using (SqlConnection con = new SqlConnection()) 
     { 
      con.open(); 

      using (SqlTransaction tr = con.BeginTransaction()) 
      { 
       DeleteAfromAllB(a,con,tr); 

       tr.Commit(); 
      } 
     } 
    } 

но, как вы можете видеть, это p retty некрасиво

ответ

1

Вызов

public void DeleteAfromAllB(Object a) 

не нужно передать SqlConnection, как вы можете ссылаться из tr.Connection. Поэтому вам просто нужен параметр SqlTransaction как параметр. Итак, для вашего первоначального вопроса, да, я думаю, что переход в SqlTransaction - это путь. Лично я предпочитаю этот путь, потому что вы можете легко отслеживать стек вызовов/область транзакции (т. Е. Когда транзакция запущена/завершена).

Другой вариант - использовать TransactionScope.

E.g.

private void DeleteAfromAllB(Object a) 
{ 
    try 
    { 
     using (var con = new SqlConnection()) 
     { 
      con.open(); 
      using (var cmd = new SqlCommand("STP_B_Delete_Referenc_To_A", con)) 
      { 
       // some parameters 
       // some sort of Execute 
       // e.g.: cmd.ExecuteNonQuery(); 
      } 
     } 
     catch (SqlException ex) 
     { 
      //ExceptionHandling 
     } 
    } 
} 

public void DeleteAfromAllB_TopLevel(Object a) 
{ 
    using (var scope = new TransactionScope()) 
    { 
     DeleteAfromAllB(a); 

     // The Complete method commits the transaction. If an exception has been thrown, 
     // Complete is not called and the transaction is rolled back. 
     scope.Complete(); 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^