2015-08-14 8 views
6

Sto utilizzando EF 6 con un modello UoW. Ho più contesti definiti nella mia UoW poiché sto utilizzando i dati da più database. Tutto sembra funzionare correttamente eccetto la funzione CommitAsync che ho definito. Ecco il codice che ho:Utilizzo di modifiche di salvataggio asincrone su Entity Framework con più contesti

public async Task CommitAsync() 
    { 
     try 
     { 
      using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) 
      { 
       if (_context1 != null) 
        await _context1.SaveChangesAsync(); 
       if (_context2 != null) 
        await _context2.SaveChangesAsync(); 

       scope.Complete(); 
      } 
     } 
     catch (DbEntityValidationException ex) 
     { 
      //.. 
     } 
    } 

Quando ho eseguito questo codice estivo a entrambi i contesti che ricevo:

Il gestore delle transazioni ha disabilitato il proprio supporto per le transazioni remote/di rete. (Eccezione da HRESULT: 0x8004D024)

Attendere _context2.SaveChangesAsync(); è dove si verifica l'errore. Se rimuovo TransactionScope da questa funzione, il codice sembra funzionare senza errori. Sono riluttante a rimuovere l'ambito per più contesti.

Solo nel caso che ti aiuto, ecco il codice che uso per chiamare questa funzione:

 state.Name = "Texas"; 
     _uow.StateRepository.Update(state); 

     user.FirstName = "John"; 
     _uow.UserRepository.Update(user); 

     await _uow.CommitAsync(); 

Grazie!

+1

Non c'è niente di sbagliato nel codice è la config sulla casella che esegue il codice msdtc ha transazioni remote/di rete disabilitate. –

+0

Perché si desidera utilizzare TransactionScope? Se il salvataggio fallisce, sarà comunque annullato. L'uso di TransactionScope porta solo a possibili deadlock. –

+2

@JamieRees Sospetto che l'OP desideri che entrambi gli aggiornamenti funzionino o che entrambi falliscano ed evitare una situazione in cui uno ha funzionato, ma uno ha fallito. –

risposta

2

L'utilizzo di due connessioni nello stesso ambito richiede MSDTC.

È possibile abilitare MSDTC per risolvere questo problema. Ma non funziona con molte soluzioni HA ed è lento.

L'unico modo per evitare l'utilizzo di MSDTC è utilizzare la stessa connessione per tutto ciò che deve essere eseguito. Dal momento che si utilizzano più database più difficili del solito. È necessario utilizzare SqlConnection.ChangeDatabase o emettere il rispettivo SQL per passare da un database all'altro sulla stessa connessione. La connessione deve essere mantenuta aperta.

In alternativa, è possibile utilizzare tre nomi di parte per i riferimenti oggetto (ad esempio DB1.dbo.MyTable).

Non c'è altro modo. MSDTC o condivisione della stessa connessione.

+0

grazie per il vostro aiuto. Suppongo che un'altra opzione è solo per rimuovere l'ambito, ma lasciata con la possibilità di quanto sopra postato da Ben. Suppongo che non sarebbe terribile nella mia situazione dato che i dati salvati nei diversi database non sono realmente correlati. –

+0

@AaronSanders se ti piace il debug dei dati incoerenti ... Questo accadrà. Il timeout può avvenire in qualsiasi momento. – usr

+0

@AaronSanders lettura aggiuntiva per te "Two Generals Problem". Questo è l'esperimento mentale che descrive il modo in cui le transazioni con hard disk FRIGGIN sono. – Aron

Problemi correlati