2014-06-13 8 views
7

Sto eseguendo un sito Web .Net MVC Azure con un database SQL Azure accessibile tramite Entity Framework 6. Intermittently (1 su un migliaio di richieste), viene visualizzato l'errore " System.ComponentModel.Win32Exception: il periodo di timeout del semaforo scaduto""Il periodo di timeout del semaforo è scaduto" SQL Azure

System.Data.SqlClient.SqlException: A transport-level error has occurred when receiving results from the server. (provider: TCP Provider, error: 0 - The semaphore timeout period has expired.) ---> System.ComponentModel.Win32Exception: The semaphore timeout period has expired

non sembra esserci alcuna ragione per esso e le richieste di prima e dopo l'errore e le loro interazioni con SQL Azure vanno bene. C'è un modo per gestire o risolvere questo.

risposta

10

SQL di Azure è molto diverso da SQL on-premise. Quando un server SQL di Azure viene sovraccaricato o si interrompe, scollega un numero di connessioni e quando si riconnette verrà inviato a un altro server SQL.

Tuttavia con le connessioni TCP non si sa se l'altra estremità ha terminato la connessione a meno che non si invii effettivamente le informazioni in basso, motivo per cui si verifica questo errore.

Una volta che il codice sa che la connessione è terminata, stabilisce una nuova connessione sulla query successiva, che funzionerà perfettamente.

Con Entity Framework 6 è ora possibile fare con Transient Fault Handling with SQL Azure using Entity Framework

Nella classe DBConfiguration è necessario impostare la vostra SetExecutionStrategy e configurarlo. Basta creare una nuova classe nel progetto ed ereditare da DbConfiguration.

public class MyConfiguration : DbConfiguration 
{ 
    public MyConfiguration() 
    { 
     SetExecutionStrategy( 
      "System.Data.SqlClient", 
      () => new SqlAzureExecutionStrategy(1, TimeSpan.FromSeconds(30))); 
    } 
} 

dettagli completi a Connection Resiliency/Retry Logic (EF6 onwards)