2012-03-29 32 views
10

Sto usando "TransactionScope", e ho bisogno di fare solo un po 'di DML all'interno del codice C#, che ho avuto successo.
Devo scoprire che qual è lo stato della Transazione, ovvero è stato completato correttamente o no?

Perché sulla base dello stato della transazione, se la transazione è completa, è necessario eseguire un reindirizzamento a un'altra pagina, altrimenti se la transazione non viene completata correttamente, è necessario mostrare l'errore nella pagina.

Voglio riorientare dopo la seguente: -
scope.Complete();
scope.Dispose();Come trovare lo stato della transazione

Please help me in questo senso.

risposta

10

Se visit the MSDN page per TransactionScope, si dovrebbe trovare questo esempio ben documentato:

try 
{ 
    // Create the TransactionScope to execute the commands, guaranteeing 
    // that both commands can commit or roll back as a single unit of work. 
    using (TransactionScope scope = new TransactionScope()) 
    { 
     using (SqlConnection connection1 = new SqlConnection(connectString1)) 
     { 
      // Opening the connection automatically enlists it in the 
      // TransactionScope as a lightweight transaction. 
      connection1.Open(); 

      // Create the SqlCommand object and execute the first command. 
      SqlCommand command1 = new SqlCommand(commandText1, connection1); 
      returnValue = command1.ExecuteNonQuery(); 
      writer.WriteLine("Rows to be affected by command1: {0}", returnValue); 

      // If you get here, this means that command1 succeeded. By nesting 
      // the using block for connection2 inside that of connection1, you 
      // conserve server and network resources as connection2 is opened 
      // only when there is a chance that the transaction can commit. 
      using (SqlConnection connection2 = new SqlConnection(connectString2)) 
      { 
       // The transaction is escalated to a full distributed 
       // transaction when connection2 is opened. 
       connection2.Open(); 

       // Execute the second command in the second database. 
       returnValue = 0; 
       SqlCommand command2 = new SqlCommand(commandText2, connection2); 
       returnValue = command2.ExecuteNonQuery(); 
       writer.WriteLine("Rows to be affected by command2: {0}", returnValue); 
      } 
     } 

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

    } 

} 
catch (TransactionAbortedException ex) 
{ 
    writer.WriteLine("TransactionAbortedException Message: {0}", ex.Message); 
} 
catch (ApplicationException ex) 
{ 
    writer.WriteLine("ApplicationException Message: {0}", ex.Message); 
} 

Il commento che contiene il massimo valore è questa:

il metodo completo commit della transazione. Se è stata generata un'eccezione, Complete non viene richiamato e la transazione viene annullata.

Quindi, se non vengono lanciate eccezioni, è possibile continuare. Metti il ​​tuo reindirizzamento dopo scope.Complete(). Se viene generata un'eccezione, la transazione ha avuto esito negativo e è stata automaticamente ripristinata. Si potrebbe doppio verificare lo stato delle transazioni (come altri hanno scritto) dopo la chiamata a Complete() e prima di reindirizzare, tramite Transaction.Current.TransactionInformation.Status:

if (Transaction.Current.TransactionInformation.Status == TransactionStatus.Committed) 
{ 
    // do redirect 
} 
+0

Grazie mille caro, hai risolto il problema in dettaglio . –

1

ne dite:

TransactionStatus status = Transaction.Current.TransactionInformation.Status; 
2

Il metodo migliore che ho trovato per l'acquisizione di questo in modo più efficiente/correttamente è come segue:

All'interno del transactioncope utilizzando l'istruzione e prima della chiamata a scope/Complete().

//Register for the transaction completed event for the current transaction 
Transaction.Current.TransactionCompleted += new TransactionCompletedEventHandler(Current_TransactionCompleted); 

Quindi creare la funzione di gestore di eventi come segue:

/// <summary> 
/// Handles the TransactionCompleted event of the Current control. 
/// </summary> 
/// <param name="sender">The source of the event.</param> 
/// <param name="e">The <see cref="System.Transactions.TransactionEventArgs"/> instance containing the event data.</param> 
static void Current_TransactionCompleted(object sender, TransactionEventArgs e) 
{ 
    if (e.Transaction.TransactionInformation.Status == TransactionStatus.Committed) 
    { 
     /// Yay it's committed code goes here! 
    } 
} 

citare MSDN

"È possibile iscriversi a questo evento, invece di utilizzare un arruolamento volatile per ottenere informazioni esiti per le transazioni.Il parametro passato al delegato TransactionCompletedEventHandler è un'istanza Transaction. È quindi possibile interrogare la proprietà TransactionInformation dell'istanza specifica per ottenere un'istanza di TransactionInformation, la cui proprietà Status contiene lo stato di una transazione con il valore Committed o Aborted. "

Problemi correlati