7

How do I commit transaction asynchronously in entity framework?

using (var transaction = this.db.Database.BeginTransaction())
{
    this.db.DoSomething();
    await this.db.SaveChangesAsync().ConfigureAwait(false);

    // note .Commit isn't async but it involves network i/o
    transaction.Commit();
}

I'd like to make .Commit asynchronous, but I don't see appropriate API in DbContextTransaction

psla
  • 306
  • 3
  • 7
  • it looks like internally it is implemented asynchronously (or at least event driven) this.InternalDispatcher.Dispatch(transaction, (Action) ((t, c) => t.Commit()), new DbTransactionInterceptionContext(interceptionContext).WithConnection(transaction.Connection), (Action) ((i, t, c) => i.Committing(t, c)), (Action) ((i, t, c) => i.Committed(t, c))); – psla May 19 '17 at 17:52
  • 1
    Possible duplicate of [Entity Framework 6 async operations and TranscationScope](http://stackoverflow.com/questions/28133801/entity-framework-6-async-operations-and-transcationscope) – Tipx May 19 '17 at 18:34
  • There is no such API in `DbContextTransaction` because there is no such API in the underlying [DbTransaction](https://msdn.microsoft.com/en-us/library/system.data.common.dbtransaction(v=vs.110).aspx) – Ivan Stoev May 19 '17 at 19:02
  • 1
    Available in EF Core 3.0 : Ref: https://learn.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.storage.idbcontexttransaction.commitasync?view=efcore-3.1&viewFallbackFrom=efcore-2.2 – ttugates May 26 '20 at 14:26

1 Answers1

2

In trying to determine the same thing, I walked through the EF6 source code for DbContext.SaveChangesAsync() to see how EF handled the committing of the implicit transaction on an async call.

Concurring with Ivan's comment on your question above, there is no mechanism for async commit in EF or System.Data.

In ObjectContext.ExecuteInTransactionAsync, which is where the transaction is handled for SaveChangesAsync, the asynchronous update routine is simply wrapped in EntityConnection.BeginTransaction and the synchronous DbTransaction.Commit. If there was a little known asynchronous asynchronous Commit, I would assume it would be used here.

This seems like a gaping hole in the asynchronous offerings for System.Data since a large transaction could potentially take a long time to commit, tying up a thread in the process. A server application with heavy database update activity could potentially lose a lot of the benefit of asynchronous code because of this.

MikeJansen
  • 3,336
  • 3
  • 26
  • 37