2012-03-05 18 views
7

Me enfrenta a un problema que me vuelve loco por un par de días, con la esperanza de que alguien me pueda ayudar. Aquí está;TransactionScope no se revierte dentro del método de servicio wcf, retrocede si se llama directamente

Estoy usando EF4 con la base de datos de Oracle, usando dotConnect for oracle de devart como proveedor. Tengo el método de servicio wcf que llama al método DeleteCabinet a continuación;

public void DeleteCabinet(string pRID) 
{ 
    using(TransactionScope tranScope = new TransactionScope()) 
    { 
     DBUtils.DeleteCabinetAndShelves(pRecordId); 

     //throw exception to test record not deleted 
     throw new Exception("xxx something has happened test xxx"); 

     tranScope.Complete(); 
    } 
} 

DBUtils.DeleteCabinetAndShelves se refiere a continuación;

public void DeleteCabinetAndShelves(string pRecordId) 
{ 
    using(var context = new EdrmEntities()) 
    { 
     var cabinet = context.Cabinets.Include("Shelves").Single(p => p.RID == pCabinetRID); 

     //mark all cabinet shelves for deletion 
     if (cabinet.Shelves != null) 
     { 
      foreach (var tempShelf in cabinet.Shelves.ToList()) 
      { 
       context.DeleteObject(tempShelf); 
      } 
     } 

     //mark cabinet for deletion 
     context.DeleteObject(cabinet); 

     //save 
     context.SaveChanges(); 
    } 
} 

cuando llamo DeleteCabinet de dentro de mi proyecto de prueba, no una llamada WCF pero el llamado método directo, funciona bien. Lanza una excepción y la transacción se retrotrae. Por lo tanto, no se elimina ningún registro de la base de datos como se esperaba

El problema es que cuando llamo al método de servicio (que llama a DeleteCabinet) desde un cliente, se lanza la excepción, pero el registro se borra de db. ¡La transacción no retrocede!

parece que llamar al método wcf no revierte la transacción, pero parece una locura (al menos para mí), ¿alguien sabe la razón por la que esto podría estar sucediendo?

Gracias de antemano

+0

Creo que esto dependerá en gran medida de sus enlaces WCF y si tienen soporte transaccional. Actualice su pregunta para revelar sus enlaces y sus declaraciones de contrato de servicio WCF. – Rabid

+0

Corrígeme si me equivoco, pero como mi servicio no está participando en una transacción iniciada por un cliente (ninguna transacción wcf en ese sentido), esas configuraciones deberían ser irrelevantes en este escenario. es decir: el método de llamada al servicio del cliente no se encuentra dentro de un workscope, es el servidor el que inicia y completa la transacción como se ve arriba. – rayback2

+1

Ohh, ya veo, eso es extraño. ¿Le permite a WCF criticar el canal o maneja la excepción en la llamada de servicio WCF y envía un resultado al cliente? ¿'EdrmEntities' está construyendo su propia 'EntityConnection' o quizás está utilizando una conexión compartida que se enlistó automáticamente en una transacción implícita fuera de su' TransactionScope'? – Rabid

Respuesta

3

te ha etiquetado su post con las etiquetas DevArt y DotConnect ... Me pregunto si esto es un problema de los proveedores de Devart en lugar de algo inherente a WCF/Entity Framework/System.Transactions. Podría probar la teoría viendo si ocurre con un ObjectContext que está utilizando el proveedor de SQL Server incorporado (o incluso el Oracle's own EF provider que se lanzó recientemente) y vea si el problema persiste. Eso es lo único que se me ocurre ya que el código parece 100% correcto.

+0

Intentado con el proveedor de Oracle, y parece funcionar. Estoy pensando que si se trataba de un error en el proveedor de devarts, se descubriría mucho antes (y se solucionaría), así que estoy pensando que debe tener algo que ver con la configuración. Se pondrá en contacto con su equipo de soporte para el problema. ' – rayback2

1

Gracias a @Rabid y @luksans comentarios constructivos problema se resuelve, y resultó que no tiene nada que ver con WCF o proveedor de ser cochecito de devart

Aquí está la cosa; El servicio wcf (que no se relanzó) y la prueba de integración (que sí lo hizo) se encuentran dentro de proyectos diferentes, por lo que los archivos de configuración son diferentes. Se salieron de sincronización en algún momento del pasado, y la diferencia está en Enlist=false parte. Entonces, la cadena de conexión del proyecto wcf tiene Enlist=false, mientras que el proyecto de prueba no. Así es como nació la ilusión de la transacción fallida de WCF.

Al eliminar Enlist=false de la cadena de conexión del proyecto wcf se solucionó el problema.

Cuestiones relacionadas