我有一个类似的方法:
public async Task SaveItemsAsync(IEnumerable<MyItem> items)
{
using (var ts = new TransactionScope())
{
foreach (var item in items)
{
await _repository.SaveItemAsync(item);
}
await _repository.DoSomethingElse();
ts.Complete();
}
}
这当然有问题,因为TransactionScope
不能很好地处理async/await。
它会失败,并显示InvalidOperationException
,并显示以下消息:
“TransactionScope必须放在创建它的同一线程上。”
我在this answer上读到了关于TransactionScopeAsyncFlowOption
的文章,这似乎正是我所需要的。
然而,对于这个特定的项目,我有一个硬要求,必须支持.Net 4.0,并且不能升级到4.5或4.5.1。因此,我的项目中的异步/等待行为是由Microsoft.Bcl.Async NuGet Package提供的。
我似乎在这个或任何其他OOB package中找不到TransactionScopeAsyncFlowOption
。我是不是错过了什么地方?
如果它不可用,有没有其他方法可以达到同样的效果?也就是说,我希望事务作用域正确地完成或回滚,尽管线程与延续交叉。
我在上面的示例中添加了DoSomethingElse
,以说明在事务范围内可能要进行多个调用,因此简单地在一次调用中将所有项传递给数据库不是一个可行的选择。
如果重要,存储库使用直接ADO.Net (SqlConnection
、SqlCommand
等)来写入SQL Server。
更新1
我想我有一个解决方案,包括从.Net 4.5.1中提取System.Transactions.dll并将其包含在我的项目中。然而,我发现这只适用于我的dev box,因为它已经安装了4.5.1。当部署到只有.Net 4.0的计算机上时,它不起作用。它只是给出了一个MissingMethodException
。我正在寻找一种可以在.Net 4.0安装上工作的解决方案。
更新2
我最初问这个问题是在2014年7月。2016年1月,end of life发布了.NET Framework4.0、4.5和4.5.1。因此,这个问题不再适用,这里仅供历史参考。
https://stackoverflow.com/questions/24593070
复制相似问题