Recentemente ho aggiornato il mio progetto da EF5 a EF6. In questo progetto ho un ruolo di lavoro di Azure che viene eseguito periodicamente e avvia una procedura memorizzata su SQL Azure che aggiorna una serie di informazioni sul database e richiede in media 1,5 ore per l'esecuzione. Al termine, il ruolo di operatore esegue attività aggiuntive con il risultato di ritorno della stored procedure.
Questo funzionava perfettamente in EF5, ma in EF6 fallisce ogni volta con uno di questi errori:
Errore Si è verificato un errore a livello di trasporto durante la ricezione dei risultati dal server. (provider: Session Provider, errore: 19 - La connessione fisica non è utilizzabile)
Errore La sessione è stata interrotta perché ha acquisito troppi blocchi. Prova a leggere o modificare meno righe in una singola transazione. Si è verificato un grave errore nel comando corrente. I risultati, se presenti, dovrebbero essere scartati.
Ho provato le seguenti cose per correggere l'errore:
WITH (NOLOCK)
SqlAzureExecutionStrategy
che è stata messa in atto e riportata indietro per utilizzare DefaultExecutionStrategy
Esempio del codice:
using (var dbContext = new EFEntityContext())
{
// set the timeout to 5 hours
var objectContext = (dbContext as IObjectContextAdapter).ObjectContext;
objectContext.CommandTimeout = 18000; // 5 hours
// update all active curriculums
var result = dbContext.usp_MyLongRunningProd();
// log the results of the operation
Trace.TraceInformation(result);
}
Inoltre, le procedure memorizzate leggono una grande tabella in un cursore, lo attraversano e si comportano come un'analisi e una modifica dei dati in base a ciascuna voce. Non ho bisogno che il cursore sia in una transazione di alcun tipo, e non ne sto usando uno che conosco, a meno che EF non ne faccia uno e questo sia il problema.
Credo che questo articolo possa avere la risposta, ma non lo saprò fino a quando il mio lavoro verrà eseguito stasera. Aggiornerò questa risposta se riuscirà:
http://entityframework.codeplex.com/discussions/454994
Che dice:
Come parte del lavoro di resilienza della connessione abbiamo modificato il comportamento predefinito di alcune API che possono produrre effetti collaterali per iniziare a utilizzare le transazioni. Abbiamo anche introdotto un modo per uscire da questo nuovo comportamento per i casi specifici in cui le transazioni non sono supportate. Ad esempio, nei nuovi overload di Database.ExecuteSqlCommand è possibile passare un nuovo parametro enum che disabilita le transazioni.