I\'m trying to commit/rollback SqlTransaction
in asynchronous. But it look like asynchronous is not supported. Is there any way to make it asynchronous without
using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
. . .
}
It doesn't look like it. Going through the relevant code, all the other methods are asynchronous through and through (the synchronous version is the special case), while SqlTransaction
and the other relevant code is synchronous only. For the parts that overlap, the SqlTransaction
simply synchronously waits for task completion (e.g. when handling reconnects).
In fact, as you get through the depths of the code, the transaction operations explicitly forbid any asynchronous operations, so not including asynchronous transaction operations seems to be by design. If you do find a workaround, keep this in mind - the system is not designed to allow concurrent operations, so always use await
as soon as you get the (whatever) task back.
If you wanted to go around this, you'd have to dig all the way down to creating the binary messages for SQL Server directly (or at least using reflection to execute some of the internal helper methods), which is not going to be all too easy (and it would require you to get access to the internal TCP connection used by SqlConnection
, of course - and handle the reconnects etc.).
Looking at EntityFramework code, their solution is pretty simple - they just call Commit
. This isn't as crazy as it might sound - the brunt of the work is done in the ExecuteXXXAsync
methods themselves, the Commit
is "free" - it only costs you the communication with the server, which usually isn't too expensive.
Given those limitations, your performance still shouldn't be affected noticeably - your thread pool might have to allocate a thread or two over the usual amount if you've got a few concurrent Commit
s, but the alternative is much more painful.
With .Net Core 3.0, it is now theoretically doable to commit or rollback asynchronously a transaction, with any transaction deriving from DbTransaction
. So with SqlTransaction
too.
See .Net Core issue #35012. (docs.microsoft.com documentation is currently lagging on this.)
But more important for your concern, so does lag SqlTransaction
underlying implementation: you can call async methods on it, but currently as far as I can see in the source code, they are still delegating to their sync counterparts through DbTransaction default implementation. And this is the case also with Microsoft.Data.SqlClient (no async overrides).
So you can get your code ready to commit or rollback asynchronously with .Net Core 3.0, but you will have to wait a bit more to get them actually async.