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

What happens if state verification fails? #4795

Open
dazinator opened this issue Aug 31, 2024 · 1 comment
Open

What happens if state verification fails? #4795

dazinator opened this issue Aug 31, 2024 · 1 comment

Comments

@dazinator
Copy link

dazinator commented Aug 31, 2024

Type of issue

Missing information

Description

As example is shown for using the verifySucceeded to check if the transaction was successful.

using var db = new BloggingContext();
var strategy = db.Database.CreateExecutionStrategy();

db.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/dotnet" });

var transaction = new TransactionRow { Id = Guid.NewGuid() };
db.Transactions.Add(transaction);

strategy.ExecuteInTransaction(
    db,
    operation: context => { context.SaveChanges(acceptAllChangesOnSuccess: false); },
    verifySucceeded: context => context.Transactions.AsNoTracking().Any(t => t.Id == transaction.Id));

db.ChangeTracker.AcceptAllChanges();
db.Transactions.Remove(transaction);
db.SaveChanges();

The documentation mentions that its likely that if the connection fails, this verifySucceeded one will fail also.
However it doesn't mention what happens in this case.

Lets say the connection drops during a transaction commit, and so the strategy retries and it invokes the verifySucceeded delegate to check if the transaction was indeed committed..

  1. What if this check fails because the db connection is still failing? Does it end up retrying the operation anyway? Or will this surface the underying exception and prevent the execution strategy from retrying?
  2. This is more of a design question checking for a possible bug. Is there a risk that when the connection originally drops during a commit - and the state of the transaction is not known to EF Core, that the retry strategy will invoke this verifySucceeded delegate - and we will check the transaction table and see that the transaction id is indeed not yet present - however the original transaction does indeed later succeed and the record will then appear afterwards? In other words can this verifySucceeded check happen "too quickly" resulting in a possible duplicate insert still? If the original transaction is very large - the commit phase might take a while no?

Page URL

https://learn.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency#execution-strategies-and-transactions

Content source URL

https://github.com/dotnet/EntityFramework.Docs/blob/main/entity-framework/core/miscellaneous/connection-resiliency.md

Document Version Independent Id

29002343-fa42-2f49-3362-53592039b26d

Article author

@AndriySvyryd

@AndriySvyryd
Copy link
Member

AndriySvyryd commented Aug 31, 2024

What if this check fails because the db connection is still failing? Does it end up retrying the operation anyway? Or will this surface the underying exception and prevent the execution strategy from retrying?

If verifySucceeded keeps throwing, then the exception will be surfaced (as usual when the retry limit is reached).

In other words can this verifySucceeded check happen "too quickly" resulting in a possible duplicate insert still? If the original transaction is very large - the commit phase might take a while no?

For that to happen the connection must fail before the commit finishes, but after it's too late to abort it. I'm not an expert on relational databases, but I'd think that period of time is orders of magnitude shorter than the time needed to establish a new connection.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants