Asynchronously commit or rollback a transaction scope
As many knows, TransactionScope
were forgotten when the async
await
pattern was introduced in .Net. They were broken if we were trying to use some await
call inside a transaction scope.
Now this is fixed thanks to a scope constructor option.
But it looks to me there is still a missing piece, at least I am unable to find how to do that in a simple "transaction scope like" way: how to await the commit or rollback of a scope?
Commit and rollback are IO operations too, they should be awaitable. But since they happen on scope disposal, we have to await the dispose. That is not doable without having IAsyncDisposable
implemented by transaction scopes, which is not currently the case.
I had a look at the System.Transactions.Transaction
interface too: no awaitable methods there either.
I understand that committing and rollbacking is almost just sending a flag to the database, so it should be fast. But with distributed transactions, that could be less fast. And anyway, that is still some blocking IO.
About distributed cases, remember this may trigger a two phases commit. In some cases additional durable resources are enlisted during the first phase (prepare). It then usually means some additional queries are issued against those lately enlisted resources. All that happening during the commit.
So is there any way to await a transaction scope? Or a System.Transactions.Transaction
instead?
Note: I do not consider this to be a duplicate of "Is it possible to commit/rollback SqlTransaction in asynchronous?". SqlTransaction
are more limited than system transactions. They can address only SQL-Server and are never distributed. Some other transactions do have async methods, such as Npgsql. Now for having async methods on transaction scopes/system transaction, DbTransaction
may be required to have async methods. (I do not know the internals of system transaction, but it is maybe using this ADO.NET contract. The way we enlist connection into system transaction does let me think it does not use it though.)
Update: DbTransaction
does have them in .Net Core 3.0, see #35012 (notably thanks to Roji).
Solution 1:
There's no way to implement it so far. But they work on it