2012-03-05 11 views
7

Sto affrontando un problema che mi fa impazzire per un paio di giorni, sperando che qualcuno possa aiutarmi. Eccolo qui;TransactionScope non esegue il rollback all'interno del metodo di servizio wcf, esegue il rollback se chiamato direttamente

Sto utilizzando EF4 con il database Oracle, utilizzando dotConnect per Oracle da devart come provider. Ho un metodo di servizio wcf che chiama il metodo DeleteCabinet di seguito;

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 si presenta come di seguito;

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(); 
    } 
} 

quando chiamo DeleteCabinet da dentro il mio progetto di test, non è una chiamata WCF ma il metodo di chiamata diretta, funziona bene. Genera eccezione e la transazione viene ripristinata. Quindi nessun record viene cancellato dal DB come previsto

Il problema è che quando chiamo metodo di servizio (che chiama DeleteCabinet) da un client, viene generata l'eccezione, ma il record IS viene eliminato da db. La transazione non si ripristina!

sembra come chiamare il metodo wcf non esegue il rollback della transazione, ma sembra folle (almeno per me), qualcuno conosce il motivo per cui ciò potrebbe accadere?

Grazie in anticipo

+0

Credo che ciò dipenderebbe in gran parte dalle associazioni WCF e dal supporto transazionale. Aggiorna la tua domanda per rivelare i tuoi binding e le tue dichiarazioni di contratti di servizio WCF. – Rabid

+0

Correggetemi se ho torto, ma poiché il mio servizio non sta partecipando a una transazione avviata da un client (nessuna transazione WCF in questo senso), tali impostazioni dovrebbero essere irrilevanti in questo scenario. Ad esempio: il metodo client call to service non è all'interno di transactioncope, è il server che avvia e completa la transazione come visto sopra. – rayback2

+1

Ohh, capisco, questo è strano. Consenti a WCF di eseguire il fault del canale o gestisci l'eccezione nella chiamata al servizio WCF e invia un risultato al client? ''ErmEntities' sta costruendo il proprio' EntityConnection' o forse sta usando una connessione condivisa che è stata automaticamente inserita in una transazione implicita al di fuori del tuo 'TransactionScope'? – Rabid

risposta

3

ti ha taggato il tuo post con le DevArt e DotConnect tag ... Mi chiedo se questo è un bug nei fornitori Devart piuttosto che qualcosa di inerente WCF/Entity Framework/System.Transactions. È possibile testare la teoria vedendo se succede con un ObjectContext che utilizza il provider SQL Server incorporato (o anche Oracle's own EF provider rilasciato di recente) e vedere se il problema si verifica ancora. Questa è l'unica cosa che posso pensare dal momento che il codice sembra corretto al 100%.

+0

Provato con il fornitore di Oracle, e sembra funzionare. Sto pensando che se fosse un bug nel provider di devart, sarebbe stato scoperto molto tempo prima (e risolto), quindi penso che debba avere qualcosa a che fare con la configurazione. Contatterà il proprio team di supporto per il problema. ' – rayback2

1

Grazie a @Rabid e @luksans commenti costruttivi problema è risolto, e si è scoperto non ha nulla a che fare con WCF o il fornitore di essere buggy di Devart

Ecco la cosa; wcf service (che non ha rollback), e test di integrazione (che ha fatto) sono all'interno di diversi progetti, quindi i file di configurazione sono diversi. Sono passati fuori sincrono in passato, e la differenza è nella parte Enlist=false. Quindi la stringa di connessione del progetto wcf ha Enlist=false mentre il progetto di test no. È così che è nata l'illusione della mancata transazione della WCF.

Rimozione Enlist=false dalla stringa di connessione del progetto wcf risolto il problema.

Problemi correlati