2017-03-15 19 views
1

AzureクラウドサービスでEntity Framework 6.1.2を使用しています。 RetryStrategyとCommitFailureHandlerの両方を追加しました。Entity Framework 6タイムアウト例外と再試行が成功しましたが、クエリが成功しました

要求が受信されると、Entity Frameworkの生のSQL部分を使用してテーブルに新しい行を挿入しようとしています。

まず、挿入するIDの行が存在するかどうかを確認します。それが存在しない場合、挿入クエリが再試行戦略が正しく再試行タイムアウト例外を投げている間

var rows = dbContext.Database.SqlQuery<T>(
    "SELECT * FROM FactState WHERE ID = @p0 ", ID 
).ToList(); 

return rows != null; 

は、我々は一度に行に

dbContext.Database.ExecuteSqlCommand(
    "INSERT INTO FactState (ID, Value) VALUES(@p0, @p1)", 
    ID, 
    Value 
); 

すべてを挿入します。 しかし、リトライでは、リトライ回数が5回に達するまでクエリがプライマリキー違反をスローします。

これはどういうことでしょう。 タイムアウト例外により、行がまったく追加されないか、またはコミットフェーズで例外が発生した場合、コミットエラーハンドラが実行され、クエリが正常に実行されたことがわかります。

私はテストプログラムでEntity Frameworkのソースを踏んできましたが、テーブルロックでタイムアウトを強制した後に手動で行を挿入することで動作をシミュレートできます。 しかし私はそれが私たちの生産環境でどうなるか理解していません。

更新

タイムアウト例外が再び週末に複数回起こっています。コミットプロセス内で例外が発生していますが、これはコミットエラーハンドラが実行されていないことを意味します。私はその可能コミット失敗ハンドラを一度に添付されていないと仮定コミット実行されている、しかし私は、Aを添付しているどのように与えられた私は、コミットの失敗ハンドラを追加するには、次のコードを使用しています

public class MyConfiguration : DbConfiguration 
{ 
    public MyConfiguration() 
    { 
     this.SetExecutionStrategy(
      "System.Data.SqlClient", 
      () => new SqlAzureExecutionStrategy()); 

     this.SetTransactionHandler(
      SqlProviderServices.ProviderInvariantName, 
      () => new CommitFailureHandler()); 
    } 
} 

理解していませんスタックトレースエラーが発生したとき

Exception: System.Data.SqlClient.SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. This failure occurred while attempting to connect to the routing destination. The duration spent while attempting to connect to the original server was - [Pre-Login] initialization=1; handshake=18; [Login] initialization=0; authentication=0; [Post-Login] complete=1; ---> System.ComponentModel.Win32Exception (0x80004005): The wait operation timed out 
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) 
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) 
at System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error) 
at System.Data.SqlClient.TdsParserStateObject.ReadSniSyncOverAsync() 
at System.Data.SqlClient.TdsParserStateObject.TryReadNetworkPacket() 
at System.Data.SqlClient.TdsParserStateObject.TryPrepareBuffer() 
at System.Data.SqlClient.TdsParserStateObject.TryReadByte(Byte& value) 
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) 
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.SqlInternalTransaction.Commit() 
at System.Data.SqlClient.SqlTransaction.Commit() 
at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext](TTarget target, Action`2 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed) 
at System.Data.Entity.Infrastructure.Interception.DbTransactionDispatcher.Commit(DbTransaction transaction, DbInterceptionContext interceptionContext) 
at System.Data.Entity.Core.EntityClient.EntityTransaction.Commit() 
+0

あなたの生産からReliableSqlConnectionを使用してみてください? –

+0

SQL Azureデータベースを使用しています – Craig

答えて

1

私は問題が再試行ではなく、接続に関連していると考えています。

あなたはVM内のSQL AzureのデータベースやSQL Serverを使用してhttps://msdn.microsoft.com/en-us/library/microsoft.practices.enterpriselibrary.windowsazure.transientfaulthandling.sqlazure.reliablesqlconnection(v=pandp.50).aspx

+0

リンクはReliableSqlConnectionがもはや維持されていないことを示していますか?現在、Entity Frameworkを使用して再試行を組み込んだ接続を処理しています。この問題を解決するためにEntity Frameworkがまだ​​存在しないReliableSqlConnectionが何を提供するのか分かりません。 – Craig

+0

EF githubプロジェクトでこの問題を報告する方が良いかもしれません。また、こちらをご覧ください:https://github.com/robdmoore/SQLAzureTransientDemo –

+1

私はEF Githubページに問題を記録しました。 https://github.com/aspnet/EntityFramework6/issues/218 – Craig