是否可以在异步中提交/回滚SqlTransaction?

时间:2015-07-01 05:10:21

标签: c# sql-server

我正在尝试在异步中提交/回滚SqlTransaction。但看起来不支持异步。有没有办法让它成为异步而不使用原始SQL来启动事务?

3 个答案:

答案 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异步提交或回滚代码,但是您需要等待更多时间才能使它们真正异步。