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