【发布时间】:2022-04-04 00:41:57
【问题描述】:
我正在尝试使用 Task.WhenAll 对数据库进行多个并行更新。代码流程是这样的。
在主方法中,我创建了一个事务范围并创建了主事务的克隆并传递给子事务。主事务被阻塞,直到子事务完成
using (var scope = DalcHelper.GetTransactionScope())
{
DependentTransaction transaction = Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete);
var task1= Dalc.UpdateDetails1(transaction );
DependentTransaction transaction1 = Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete);
var task2 = Dalc.UpdateDetails2(transaction1);
await Task.WhenAll(task1, task2 ).ConfigureAwait(false);
scope.Complete();
}
DalcMethod 是这样的。在这里,从外部事务创建的克隆作为参数。依赖事务完成通知主事务依赖完成
try
{
using (SqlCommand databaseCommand = DalcHelper.GetCommand(SPName))
using (var scope = new TransactionScope(dependentCloneTransaction, TransactionScopeAsyncFlowOption.Enabled))
{
-- Update database
scope.Complete();
}
}
finally
{
//Call complete on the dependent transaction
dependentCloneTransaction.Complete();
}
dalc 方法是返回 Task 的异步方法
我得到以下异常
事务已中止。尝试提升事务时失败。已经有一个打开的与此命令关联的 DataReader,必须先关闭它。等待操作超时
。谁能告诉我我在这里做错了什么?
【问题讨论】:
-
在这种情况下,问题似乎有所不同,与
Async or TPL无关,它作为本地事务开始,当您在同一事务上下文中打开多个资源(连接)时,它确实被提升为分布式事务,由于某些限制而失败。第二个问题似乎是你试图在Command对象上ExecuteReader,当原始Reader仍然存在时,这是一个实时连接,首先关闭它以运行第二个ExecuteNonQuery
标签: c# multithreading async-await task-parallel-library transactionscope