我正在尝试在异步中提交/回滚SqlTransaction
。但看起来不支持异步。有没有办法让它成为异步而不使用原始SQL来启动事务?
答案 0 :(得分:7)
看起来不像。通过相关代码,所有其他方法都是异步的(同步版本是特殊情况),而SqlTransaction
和其他相关代码只是同步的。对于重叠的部分,SqlTransaction
只是同步等待任务完成(例如,处理重新连接时)。
事实上,当您深入了解代码时,事务操作明确禁止任何异步操作,因此不包括异步事务操作似乎是设计使然。如果您确实找到了解决方法,请记住这一点 - 系统不是为了允许并发操作而设计的,所以 总是一旦得到(无论如何)任务,就会使用await
。< / p>
如果你想解决这个问题,你必须一直深入研究直接为SQL Server创建二进制消息(或者至少使用反射来执行一些内部帮助器方法),这是不会的太容易了(当然,它需要你访问SqlConnection
使用的内部TCP连接 - 并处理重新连接等。)。
查看EntityFramework代码,他们的解决方案非常简单 - 他们只需调用Commit
。这并不像它听起来那么疯狂 - 工作的主要内容是ExecuteXXXAsync
方法本身,Commit
是“免费的” - 只需要与服务器进行通信,通常不太贵。
鉴于这些限制,您的性能仍然不应受到显着影响 - 如果您有一些并发Commit
s,您的线程池可能必须分配一个或两个一个或多个线程,但替代方案更加痛苦。
答案 1 :(得分:3)
using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
. . .
}
答案 2 :(得分:0)
使用.Net Core 3.0,从理论上讲现在可以异步提交或回滚事务,而任何事务都源自DbTransaction
。所以也SqlTransaction
。
请参见.Net Core issue #35012。 docs.microsoft.com文档目前滞后于此。
但对于您而言,更重要的是,滞后SqlTransaction
的基础实现也是如此:您可以在其上调用异步方法,但是据我目前在source code中所看到的,它们仍然委托给通过DbTransaction
default implementation与他们同步。 Microsoft.Data.SqlClient
(没有异步覆盖)也是如此。
因此,您可以准备使用.Net Core 3.0异步提交或回滚代码,但是您需要等待更多时间才能使它们真正异步。