Sto cercando un modo per eseguire una query mentre TransactionScope è vivo, e ignoro TransactionScope: in pratica, voglio eseguire questa particolare query indipendentemente da cosa.Ignora TransactionScope per query specifiche
Sto utilizzando il codice EF, e il modo in cui l'applicazione è progettata, un nuovo contesto di dati viene aperto più volte in una singola chiamata, ognuno con le proprie modifiche e tutte queste sono contenute in un singolo TransactionScope , che ha chiamato Complete()
alla fine, senza problemi. All'interno del contesto abbiamo sovrascritto lo SaveChanges
in modo che se si verifica un'eccezione su base.SaveChanges()
, possiamo prenderlo e accedere al database prima di eseguire il rollback della transazione.
Poiché il SaveChanges
si verifica all'interno della transazione, la registrazione ovviamente non si verifica, perché appartiene alla stessa transazione della chiamata originale. Sto cercando di ignorare completamente TransactionScope solo per il codice di registrazione.
Ecco po 'di codice stripped-down:
// From the context
public override int SaveChanges() {
try {
return base.SaveChanges();
} catch (Exception ex) {
// Writes to the log table - I want this to run no matter what
LogRepo.Log(/*stuff to log from the context*/);
throw;
}
}
// Inside the business logic
public void DoSomething() {
try {
using (var scope = new TransactionScope()) {
using (var context = new FooContext()) {
// Do something
context.SaveChanges();
}
using (var context = new FooContext()) {
// Do something else
context.SaveChanges();
}
scope.Complete();
}
} catch (Exception ex) {
// scope.Complete is never called, so the transaction is rolled back
}
}
Ho provato ad utilizzare ADO.NET regolare invece di EF per la registrazione, ma ancora gli stessi risultati - si ottiene il rollback troppo.
Ho bisogno che la gestione degli errori si verifichi all'interno di SaveChanges
, perché quello che sto registrando è lo stato delle entità che vengono salvate - quindi non posso semplicemente spostare facilmente la registrazione da qualche altra parte. Potrei costruire il messaggio all'interno dello SaveChanges catch
, e lanciarlo e lasciare che sia DoSomething catch
loggarlo, ma ci sono dozzine di metodi DoSomething
, e preferirei semplicemente occuparmene in un posto.
Perfetto! Esattamente quello che stavo cercando. Testato e funziona sia in ADO.NET regolare che in Entity Framework Grazie –
Appena implementato questo e ora ottengo questo errore: L'accesso di rete per Distributed Transaction Manager (MSDTC) è stato disabilitato. Abilitare DTC per l'accesso alla rete nella configurazione di sicurezza per MSDTC utilizzando lo strumento di amministrazione dei componenti. più transazioni possono causare questo errore? –
Questo mi ha salvato un sacco di mal di testa! Sto elaborando i messaggi MSMQ all'interno di una transazione, ma devo raggiungere SQL Azure per un po 'di dati extra e non supportano DTC. ha permesso alle mie transazioni di funzionare ancora, pur lasciando funzionare anche la funzione di Azure. – RubyHaus