2011-02-28 13 views
8

Soy un novato en C#. Entonces, ¿me preguntaba si alguien puede ayudarme a descubrir cómo funciona C# con transactionscope? Porque estoy un poco confundido por la definición de eso. Sin embargo, déjame explicarte un poco sobre mi problema. Para que puedas saber lo que estoy tratando de lograr.Opciones de .NET Transactioncope

he declarado tres adaptador de mesa para tres conjunto de datos diferente como esto:

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

El proceso para importar datos es:

  1. Primero insertar una entrada de registro a través de logAdap.insert método() .
  2. Pasa a través de un archivo de Excel para tomar las medidas y comienza a insertar mediante el método measAdap.insert().
  3. Foreach measurement Estoy insertando valores mediante el método valueAdap.insert().

Así que mi pregunta es - desde la medición & valor tiene una relación anidada. ¿Cómo puedo crear un workscope anidado & cuando ocurre un error en cualquier lugar (inserción/inserción de valores de medición)? Solo quiero revertir todo lo que hice. Es solo que quiero volver al punto antes de que insertara la entrada de registro.

+0

BTW no existe tal cosa como "C# .NET". Es solo "C#". –

Respuesta

0

no necesita más de un TransactionScope, puede hacer todo en la misma, creo.

+0

Así que creo que la lógica de pseudo sería algo como esto: 'code' usando (TransactionScope ts = new TransactionScope()) { \t tratar \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(); } catch (Excepción ex) { measAdap.Rollback(); valAdap.Rollback(); \t} } 'código' – Mystic

+0

@Mystic utilizando esa lógica, la transacción se promueve utilizando el coordinador de transacciones distribuidas. Esta respuesta SO te dice por qué probablemente no quieres eso: http://bit.ly/gGampm - mira mi respuesta para la solución alternativa. – jevakallio

2

Citando este artículo acertadamente nombrado: The definitive TableAdapters + Transactions blog post.

si se está trabajando con múltiples operaciones dentro de una TransactionScope, es decir, “GetData” y “Actualizar”, tanto dentro de una sola TransactionScope, o dos Actualización de dentro de un TransactionScope, se quiere efectivamente abiertas dos SqlConnections a la base de datos única, y por lo tanto, promover innecesariamente la transacción de LTM a MSDTC. Como buena práctica, SIEMPRE envuelva solo una operación singular dentro de un TransactionScope. Si elige envolver varias operaciones dentro de un solo TransactionScope, en ese caso debe administrar la vida de la conexión extendiendo la definición de clase parcial. En otras palabras, el siguiente código hará que la transacción para promover -

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

Pero el siguiente código está bien -

using (TransactionScope tsc = new TransactionScope()) 
{ 

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

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

lo que sólo necesita una TransactionScope, pero con algunas advertencias. Aquí está la esencia, pero te animo a leer la publicación del blog.

TableAdapters no son la metodología de acceso a datos más adecuada para sistemas transaccionales de alta integridad. Si necesita más confiabilidad, probablemente deba escribir su operación como un procedimiento almacenado y ejecutarla desde su código C#.

0

Como creo que lo que busca es cómo utilizar el TransactonScope, esto es lo que el código se vería así, modificando un poco el ejemplo en tu comentario:

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. 
    }} 

Esta manera de usar el alcance se denomina transacciones implícitas y puede obtener una buena descripción de eso en este artículo de MSDN: Implementing an Implicit Transaction using Transaction Scope.

Habiendo dicho eso, lo que fencliff menciona es cierto, ya que probablemente no quiera abrir múltiples conexiones para su escenario, guardando valiosos recursos de la base de datos.