2011-02-28 3 views
8

Sono un novizio in C#. Quindi mi stavo chiedendo se qualcuno può aiutarmi a capire come C# funziona con transactioncope? Perché sono un po 'confuso dalla definizione di esso. Tuttavia, mi permetta di spiegare un po 'il mio problema. In modo che tu possa sapere cosa sto cercando di ottenere.Opzioni .NET Transactionscope

ho tre adattatore tavolo dichiarato per tre set di dati diversi in questo modo:

logTableAdapter logAdap = new logTableAdapter(); 
measTableAdapter measAdap = new measTableAdapter(); 
valueTableAdapter valueAdap = new valueTableAdapter(); 

Il processo per importare i dati è:

  1. prima cosa inserire una voce di registro tramite logAdap.insert il metodo() .
  2. Passare attraverso un file excel per acquisire le misurazioni e iniziare l'inserimento tramite il metodo measAdap.insert().
  3. Foreach measurement sto inserendo i valori tramite il metodo valueAdap.insert().

Quindi la mia domanda è - poiché il valore di misurazione & ha una relazione nidificata. Come posso creare un transactioncope nidificato & quando si verifica un errore ovunque (inserimento della misura/inserimento del valore) voglio solo eseguire il rollback di tutto ciò che ho fatto. Voglio solo tornare al punto precedente all'inserimento della voce di registro.

+0

BTW non esiste "C# .NET". È solo "C#". –

risposta

0

Non hai bisogno di più di un TransactionScope, puoi fare tutto nello stesso modo in cui penso.

+0

Così si pensa la logica pseudo sarebbe qualcosa di simile a questo: 'Codice delle usando (TransactionScope ts = new TransactionScope()) { \t provare \t { \t \t foreach (.....) { \t \t \t measAdap.InsertMeas (.....); \t \t \t foreach (.....) \t \t \t { \t \t \t valAdap.InsertVal (.....); \t \t \t} \t \t} \t \t \t measAdap.Commit(); \t valAdap.Commit(); } cattura (Eccezione ex) { measAdap.Rollback(); valAdap.Rollback(); \t} } 'code' – Mystic

+0

@Mystic utilizzando tale logica viene promossa la transazione utilizzando il coordinatore della transazione distribuita. Questa risposta SO ti dice perché probabilmente non vuoi che: http://bit.ly/gGampm - vedi la mia risposta per risolvere il problema. – jevakallio

2

Citando questo articolo con nome appropriato: The definitive TableAdapters + Transactions blog post.

se si sta lavorando con le operazioni plurali all'interno di una TransactionScope, vale a dire “GetData” e “Aggiorna” sia all'interno di un singolo TransactionScope, o due Update all'interno di un TransactionScope, sarà effettivamente aperte due SqlConnections al singolo database, e quindi promuovere inutilmente la transazione da LTM a MSDTC. Come best practice, SEMPRE avvolgere solo un'operazione singolare all'interno di TransactionScope. Se si sceglie di eseguire il wrapping di più operazioni all'interno di un singolo TransactionScope, in questo caso è necessario gestire autonomamente la durata della connessione estendendo la definizione della classe parziale. In altre parole, il seguente codice farà sì che la transazione per promuovere -

using (TransactionScope tsc = new TransactionScope()) 
{ 
    tableAdap.GetData() ; 
    //Do your transactional work. 
    tableAdap.Update() ; 
    tsc.Complete() ; 
} 

Ma il seguente codice è proprio bene -

using (TransactionScope tsc = new TransactionScope()) 
{ 

    tableAdap.OpenConnection() ; 
    tableAdap.GetData() ; 

    //Do your transactional work. 
    tableAdap.Update() ; 
    tableAdap.CloseConnection() ; 
    tsc.Complete() ; 
} 

Quindi è necessario un solo TransactionScope, ma con alcuni avvertimenti. Ecco il succo, ma ti incoraggio a leggere il post del blog.

TableAdapters non sono la metodologia di accesso ai dati più adatta per i sistemi transazionali ad alta integrità. Se hai bisogno di più affidabilità, probabilmente dovresti scrivere la tua operazione come stored procedure ed eseguirla dal tuo codice C#.

0

Come penso che quello che stavi cercando è come utilizzare il TransactonScope, qui è quello che il codice sarebbe simile, modificando un po 'l'esempio nel tuo commento:

using(TransactionScope ts = new TransactionScope()) { 
    try 
    { 
     logAdap.InsertLog(.....); 

     foreach (.....) 
     { 
      measAdap.InsertMeas(.....); 
      foreach (.....) 
      { 
       valAdap.InsertVal(.....); 
      } 
     } 

     // Complete the transaction 
     ts.Complete(); 
    } 
    catch (Exception ex) 
    { 
     // Your error handling here. 
     // No need to rollback each table adapter. That along with all the 
     // transaction is done for you when exiting the using block without 
     // calling Complete() on the TransactionScope. 
    }} 

Questo modo di usare l'ambito è denominato transazioni implicite e puoi ottenere una buona panoramica di ciò in questo articolo di MSDN: Implementing an Implicit Transaction using Transaction Scope.

Detto questo, ciò che menziona fencliff è vero, poiché probabilmente non si desidera aprire più connessioni per lo scenario, salvando preziose risorse di database.