简体   繁体   中英

Is it possible to commit/rollback SqlTransaction in asynchronous?

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 raw SQL to start transaction?

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 (eg 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 . (Or DbTransaction documentation .)

But more important for your concern, SqlTransaction underlying implementation does not leverage it yet: 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.

using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
    . . .
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM