2011-12-08 9 views
18

Utilizzando Entity Framework, ho ricevuto una serie di le seguenti eccezioni la scorsa notte in una delle mie applicazioni:System.Data.EntityException: Il provider sottostante fallito su Commit

System.Data.EntityException: The underlying provider failed on Commit. ---> 
System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior 
to completion of the operation or the server is not responding.  
    at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) 
    at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()  
    at System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error) 
    at System.Data.SqlClient.TdsParserStateObject.ReadSni(DbAsyncResult asyncResult, TdsParserStateObject stateObj) 
    at System.Data.SqlClient.TdsParserStateObject.ReadNetworkPacket()  
    at System.Data.SqlClient.TdsParserStateObject.ReadBuffer()  
    at System.Data.SqlClient.TdsParserStateObject.ReadByte()  
    at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler,SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)  
    at System.Data.SqlClient.TdsParser.TdsExecuteTransactionManagerRequest(Byte[] buffer, TransactionManagerRequestType request, String transactionName, TransactionManagerIsolationLevel isoLevel, Int32 timeout, SqlInternalTransaction transaction, TdsParserStateObject stateObj, Boolean isDelegateControlRequest) 
    at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransactionYukon(TransactionRequest transactionRequest, String transactionName, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)  
    at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransaction(TransactionRequest transactionRequest, String name, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest) 
    at System.Data.SqlClient.SqlInternalTransaction.Commit()  
    at System.Data.SqlClient.SqlTransaction.Commit() 
    at System.Data.EntityClient.EntityTransaction.Commit()  
    --- End of inner exception stack trace ---  
    at System.Data.EntityClient.EntityTransaction.Commit()  
    at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options)  
    at System.Data.Entity.Internal.InternalContext.SaveChanges()  
    at System.Data.Entity.Internal.LazyInternalContext.SaveChanges() 

La cosa interessante di questo errore è che il i dati sono stati effettivamente scritti nel database. I found a related post on a MS site sembrava indicare che si trattava di un errore relativo alla rete.

Alcune domande che potrei usare assistenza sono:

  1. Quali opzioni devo disturbare il tiro questo errore?
  2. E 'più probabile che sia collegato alla rete o il DB potrebbe essere un sospetto?
  3. Come posso sapere dal codice se la transazione è stata effettivamente completata?
  4. Devo interrogare il DB su questo errore per verificare se il successo o semplicemente riprovare la transazione?
  5. Se riprovo la transazione, come può essere eseguita automaticamente con Entity Framework o semplicemente riprendo/riprovo?
  6. Quali altri articoli dovrei guardare?

Grazie in anticipo.

UPDATE

Usando Ignite for SQL siamo stati in grado di determinare che un processo di SQL secondario da un altro gruppo è stato monopolizzando la CPU impedendo la nostra applicazione di funzionare correttamente. In breve, stiamo andando avanti con l'aggiunta di un server secondario per prevenire ulteriori conflitti tra i due team.

Ciò che è ancora interessante dell'eccezione è che la transazione è effettivamente riuscita, piuttosto che fallita.

+0

So che è passato molto tempo, ma puoi approfondire come hai usato Ignite per SQL? Nel mio caso non sempre accade, quindi è difficile sapere quando guardare il server. – gitsitgo

+0

Non posso dire di essere un ignite guru; abbiamo un team di prestazioni DB che gestisce questa roba. Posso dire che quello che cerco di solito quando ottengo problemi di prestazioni sono le istruzioni top di sql (come gli stati di accensione "le barre grandi"). Queste sono in genere le query che eseguono il hogging di tutto. Da lì si tratta di mettere a punto quelle domande. Mi dispiace di non poter fornire più specifiche che stai cercando. In bocca al lupo. – Randy

risposta

1

La mia scommessa è che la risposta di successo dal comando di commit della transazione non è stata inviata (o non è stata inviata abbastanza velocemente) causando un'eccezione nel codice. Un caso davvero pazzo. Eccezioni di questo tipo non significano necessariamente che l'esecuzione effettiva del comando abbia avuto esito negativo, solo che è stato riscontrato un errore A.

Allo stesso modo, se si verificava un problema durante l'invio della risposta da una chiamata di servizio Web, ciò non implicherebbe necessariamente che gli effetti collaterali di quella chiamata non fossero stati applicati.

+0

Luke, grazie per il tuo commento. Hai sicuramente l'idea giusta. Ho visto la stessa cosa nel codice WS in cui il WS ha elaborato la richiesta, ma la risposta è scaduta. Mi fa impazzire quando ciò accade, perché non hai modo di "sapere" se le cose effettivamente funzionano; questo è a meno che non si vogliano codificare i servizi che possono essere chiamati per verificare che le cose effettivamente funzionino. ;-) – Randy

+1

@Randy è in realtà una cosa molto simile a nelle reti di computer con TCP. Il principio è che se non riceviamo la conferma che un messaggio è stato consegnato, lo riproviamo fino a quando non lo facciamo, tuttavia ciò significa che il messaggio (in questo caso la transazione del database) deve essere idempotente (cioè rigiocabile) che non è il caso con transazioni di database –

0

+1 per Luke, l'esplosione è buona. La formulazione dell'errore è sfortunata.

System.Data.EntityException: **The underlying provider failed on Commit.** ---> 
System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior 

deve essere letto

System.Data.EntityException: **The underlying provider failed to respond to Commit** 
System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior 

le probabili cause sono problemi di rete o server. ad es. 100 CPU, o altro ritardo del server, sono tutti ancora corretti. MA NON SAI se ha commesso o meno, se questo è un caso di timeout. Se una risposta è stata ricevuta con esito negativo, il DB dovrebbe essere ripristinato. Ovviamente, se ciò non si verifica, il database ha ummm si è bloccato e ha provocato una potenziale corruzione. Rare, spero.

Ho visto in un tavolo da 1 miliardo + righe ...Durante l'allocazione dello spazio in fase di crescita, poiché l'area dell'indice e dei dati deve espandersi, occorrono più di 30 secondi. MA il COMMIT DID è successo. Il cliente era scaduto. Le re-org online possono causare ritardi del genere (ben visto almeno su DB2)

Problemi correlati