Why does SqlAzureExecutionStrategy not handle error: 19 - Physical connection is not usable

前端 未结 5 504
我在风中等你
我在风中等你 2021-02-04 07:12

Full exception:

System.Data.Entity.Core.EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for de         


        
5条回答
  •  太阳男子
    2021-02-04 07:49

    From the profiler trace we observe that the same connection is used for each query database query. This is by design and as discussed early, i.e. when a connection is explicitly opened by the developer it tells EF not to open/reopen a connection for each command.

    Well this certainly does not sound like general statement. What profiler trace? Why suppose connection explicitly opened by the developer and handled to the EF? I dont see anything like this in original question (and it is not common practice with EF).

    So the questions remain unanswered: Why isn't this handled by the SqlAzureExecutionStrategy? Is it a good idea to write an own DbExecutionStrategy that handles this one?

    Since I can see this error in my Azure service from time to time, I decided to test it. Here is my strategy:

    public class ExtendedSqlAzureExecutionStrategy : SqlAzureExecutionStrategy
        {
            public ExtendedSqlAzureExecutionStrategy(int maxRetryCount, TimeSpan maxDelay) : base(maxRetryCount, maxDelay) 
            { }
    
            protected override bool ShouldRetryOn(Exception exception)
            {
                return base.ShouldRetryOn(exception) || IsPhysicalConnectionNotUsableSqlException(exception);
            }
    
            private bool IsPhysicalConnectionNotUsableSqlException(Exception ex)
            {
                var sqlException = ex as SqlException;
                if (sqlException != null)
                {
                    // Enumerate through all errors found in the exception.
                    foreach (SqlError err in sqlException.Errors)
                    {
                        if (err.Number == 19)
                        {
                            return true;
                        }                    
                    }
                }
    
                return false;
            }
        }
    

    EDIT

    Ok, so after some time and logging I can tell that the strategy based on

    if (err.Number == 19)
    

    is wrong. Actual SqlException object for this error has ErrorCode = -2146232060 and Number = -1 - I could not find any documentation for those, so I decided not to base strategy on them. For now I am trying trivial check:

    public class ExtendedSqlAzureExecutionStrategy : SqlAzureExecutionStrategy
        {
            public ExtendedSqlAzureExecutionStrategy(int maxRetryCount, TimeSpan maxDelay) : base(maxRetryCount, maxDelay) 
            { }
    
            protected override bool ShouldRetryOn(Exception exception)
            {
                return base.ShouldRetryOn(exception) || IsPhysicalConnectionNotUsableSqlException(exception);
            }
    
            private bool IsPhysicalConnectionNotUsableSqlException(Exception ex)
            {
                var sqlException = ex as SqlException;
                if (sqlException != null)
                {
                    return sqlException.Message.Contains("Physical connection is not usable");
                }
    
                return false;
            }
        }
    

    EDIT 2:

    It works. No more Physical connection is not usable errors at all, and no RetryLimitExceededException, so this error is in fact transient (solvable by retry), so I think it should be included in SqlAzureExecutionStrategy.

提交回复
热议问题