两个SqlConnections,一个TransactionScope

时间:2018-07-03 17:48:13

标签: async-await transactionscope sql-server-2017 connection-pool

尝试在单个TransactionScope下同时发出两个查询时,我的应用程序抛出错误。

例如,使用Entity Framework,我将创建两个单独的DbContext实例,并在同一ToListAsync中对它们中的每个实例启动异步操作(即TransactionScope),然后用Task等待两个返回的Task.WhenAll。目的是在数据库服务器上同时运行两个I / O绑定操作时,将这两个查询尽快发送到服务器,并将主请求线程释放回池中。

这种方法有时会引发错误:

  

该操作对于交易状态无效

这是可预测的比赛情况吗?例如,如果我在开始第二项任务(或其余的N-1项任务)之前await进行了第一项任务,那么在没有竞争条件的情况下,一切并行运行良好。但是,如果我不等待第一个任务,而是同时启动所有剩余任务,则似乎其中两个(或多个)都在尝试同时建立事务和TransactionScope实例,如果不是数据库服务器本身,就会感到困惑。

我读了一篇文章,暗示在单个TransactionScope中打开两个连接是无效的。虽然我不认为是这种情况(在同一笔交易中打开两个连接只会将其升级为分布式交易),但我确实相信这会导致某种竞争状况,如我所描述。

由上述情况引起的另一个问题确实很糟糕。分布式事务失败后,每次尝试打开我的服务器上的连接都会导致以下错误:

  

已完成分布式事务。将此会话注册为新事务或NULL事务。

此错误发生在不相关代码(仍在同一运行的Web应用程序中)的DbContext的全新实例中,这些实例没有包装在任何类型的事务中,这向我提示连接池中的连接具有已损坏。

TransactionScope breaking SqlConnection pooling?

0 个答案:

没有答案