2009-02-25 8 views
0

Voici mon exigence est comme ceci:Comment puis-je exécuter plusieurs transactions sous la même connexion?

  1. Dans un premier temps j'exécuter une procédure stockée pour insérer \ mettre à jour un enregistrement dans DB, sous une seule transaction.
  2. Si l'exécution du SP échoue en raison d'un problème, je dois être en mesure d'invoquer à nouveau le SP sous une transaction différente.
  3. Même si la ré-invocation de SP échoue alors seulement, je devrais jeter une erreur à la fonction d'appel.

Voici l'exemple de code. Est-ce la bonne façon de gérer les transactions et les erreurs, ou existe-t-il une meilleure façon de le faire?

public void InsertUser(string code) 
{ 
    bool bRetry=false; 
    SqlTransaction transaction = null; 
    Exception RetrunEx = null; 
    using (SqlConnection sqlConnection = new SqlConnection(this.connectionString)) 
    { 
     sqlConnection.Open(); 

     SqlCommand sqlCommand = new SqlCommand("InsertUser", sqlConnection); 
     sqlCommand.CommandType = System.Data.CommandType.StoredProcedure; 
     SqlParameter param = sqlCommand.Parameters.Add("@UserCode", SqlDbTypes.VarChar); 
     param.Value = code; 

     //Is this the proper place to begin a transaction? 
     SqlTransaction transaction = connection.BeginTransaction(); 
     sqlCommand.Transaction = transaction;  

     try 
     {   
      sqlCommand.ExecuteNonQuery(); 
      transaction.Commit(); 

     }  
     catch(SqlException SqlEx) 
     { 
     transaction.Rollback(); 
    bRetry = true; 
     RetrunEx = SqlEx; 
     } 
     catch(Exception ex) 
     { 
      transaction.Rollback(); 
      RetrunEx = ex; 
     } 

     //Will this be treated as new transaction? 
     //Is there any best way of doing this? 
     transaction = connection.BeginTransaction(); 
     sqlCommand.Transaction = transaction; 

     try 
     { 
      if (bRetry)   
     { 
       sqlCommand.ExecuteNonQuery(); 
       transaction.Commit(); 
       ReturnEx = null; 
      } 

     }  
     catch(Exception Ex) 
     { 
     transaction.Rollback(); 
     RetrunEx = Ex; 
     } 

     //When both the trials fails then throw exception 
     if (RetrunEx != null) 
     { 
      throw RetrunEx; 
     } 
    } 
} 

Répondre

1

La meilleure façon de travailler avec la transaction est d'utiliser System.Transaction Il est un api très simple mais puissant.

... 
using (TransactionScope ts = new TransactionScope()) 
{ 
    //Do Transactional Work 
    ... 
    ... 

    //Commit your transaction 
    ts.Complete(); 
} 

Vous n'avez pas besoin de try/catch pour annuler votre transaction. Si vous quittez le "using" avec une exception, ou sans appeler l'instruction "ts.Complete", votre transaction sera automatiquement annulée.

0

Je n'aurais probablement qu'une méthode dont le seul but est d'essayer une procédure stockée. Code Pseudo:

public bool ExecuteSP() 
{ 
    try{ 
    //open connection, begin tran execture sp 
    //commit transaction, return true; 
    } 

    catch(SqlException){ 

    //rollback transaction 
    //return false 
    } 

} 

Puis dans votre code d'appel, vous pouvez simplement faire quelque chose comme ceci:

if(!ExecuteSP() && !ExecuteSP()) 
{ 
    //throw Exception 
} 
Questions connexes