Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ExecutionStrategy ignored when doing ToList() in EF Core 3.0 #18628

Closed
douggish opened this issue Oct 28, 2019 · 1 comment · Fixed by #18691
Closed

ExecutionStrategy ignored when doing ToList() in EF Core 3.0 #18628

douggish opened this issue Oct 28, 2019 · 1 comment · Fixed by #18691
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported providers-beware regression type-bug
Milestone

Comments

@douggish
Copy link

The configured execution strategy (either a custom one or SqlServerRetryingExecutionStrategy via e.g. EnableRetryOnFailure()) is not being used when ToList() is called on a DbSet.

It does seems to be used when SaveChanges() is called, however.

In EF Core 2.2, the execution strategy would be used for queries (e.g. ToList()) as well as on SaveChanges().

This is causing our queries to fail occasionally due to deadlocks:

Microsoft.Data.SqlClient.SqlException (0x80131904): Transaction (Process ID 134) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
   at Microsoft.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at Microsoft.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at Microsoft.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at Microsoft.Data.SqlClient.SqlDataReader.TryHasMoreRows(Boolean& moreRows)
   at Microsoft.Data.SqlClient.SqlDataReader.TryReadInternal(Boolean setTimeout, Boolean& more)
   at Microsoft.Data.SqlClient.SqlDataReader.<>c__DisplayClass195_0.<ReadAsync>b__1(Task t)
   at Microsoft.Data.SqlClient.SqlDataReader.InvokeRetryable[T](Func`2 moreFunc, TaskCompletionSource`1 source, IDisposable objectToDispose)
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.AsyncQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)

without it attempting to retry.

Steps to reproduce

  1. Create a custom execution strategy:
public class TestExecutionStrategy : SqlServerRetryingExecutionStrategy
{
    public TestExecutionStrategy(ExecutionStrategyDependencies dependencies) : base(dependencies)
    {
    }

    protected override void OnFirstExecution()
    {
        Console.WriteLine("OnFirstExecutionCalled");
        base.OnFirstExecution();
    }
}
  1. Configure DbContext to use custom execution strategy:
services.AddDbContext<TestDbContext>(o =>
    o.UseSqlServer(connectionString,
        options => options.ExecutionStrategy(d => new TestExecutionStrategy(d))));
  1. Call a method that does a ToList() on a DbSet:
List<Order> orders = _dbContext.Orders.ToList();
  1. Note that OnFirstExecution() is not called.

Further technical details

EF Core version: 3.0.0
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET Core 3.0
Operating system: macOS High Sierra
IDE: Rider 2019.2.3

@ajcvickers
Copy link
Member

@AndriySvyryd Thoughts?

@AndriySvyryd AndriySvyryd self-assigned this Oct 29, 2019
@AndriySvyryd AndriySvyryd added this to the 3.1.0 milestone Oct 29, 2019
AndriySvyryd added a commit that referenced this issue Oct 31, 2019
Move the retry scope for SaveChanges to properly reset the state before retrying.

Fixes #18628
AndriySvyryd added a commit that referenced this issue Nov 1, 2019
Move the retry scope for SaveChanges to properly reset the state before retrying.

Fixes #18628
@ajcvickers ajcvickers added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Nov 1, 2019
@AndriySvyryd AndriySvyryd removed their assignment Nov 1, 2019
AndriySvyryd added a commit that referenced this issue Nov 1, 2019
Move the retry scope for SaveChanges to properly reset the state before retrying.

Fixes #18628
AndriySvyryd added a commit that referenced this issue Nov 1, 2019
Move the retry scope for SaveChanges to properly reset the state before retrying.

Fixes #18628
AndriySvyryd added a commit that referenced this issue Nov 1, 2019
Move the retry scope for SaveChanges to properly reset the state before retrying.

Fixes #18628
AndriySvyryd added a commit that referenced this issue Nov 2, 2019
Move the retry scope for SaveChanges to properly reset the state before retrying.

Fixes #18628
@ajcvickers ajcvickers modified the milestones: 3.1.0-preview3, 3.1.0 Dec 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported providers-beware regression type-bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants