我有一个.NET Core C#控制台应用程序,它执行大量计算,然后使用Dapper(和Dapper.Contrib)将结果写入SQL Server 2016 Developer Edition数据库。我遇到的问题是,当我并行运行大量项目(例如,大于1000)时,我开始在.Open()
调用上遇到间歇性连接失败,说
发生与网络相关或特定于实例的错误......
这通常在已成功插入数千行后发生。
代码的简化版本如下所示:
Parallel.ForEach(collection, (item) =>
{
var results = item.Calculate(parameters);
dal.Results.Insert(results);
allResults.AddRange(results);
});
在Insert方法中,它看起来像这样:
public override void Insert(IEnumerable<Result> entities)
{
using (var connection = GetConnection())
{
connection.Open();
using (var transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted))
{
connection.Insert(entities, transaction);
transaction.Commit();
}
}
}
关于代码的其他一些我认为不会影响这个但可能相关的代码:
dal.Results
只是一个包含Insert()
方法的存储库,并且预先初始化了一个连接字符串,用于每次new SqlConnection(connectionString)
GetConnection()
时实例化allResults
调用。
ConcurrentBag<Result>
是Parallel.ForEach
,我用它来存储所有结果,以便以后在VALUES()
我正在使用一个交易,因为它似乎以这种方式表现更好,但如果可能导致问题,我愿意接受建议。
提前感谢您对此问题的任何指导!
答案 0 :(得分:1)
并行执行大量IO绑定的数据库操作没有任何优势。
您应该创建发烧但是要插入更大的数据串,并尽量减少数据库事务。这可以通过以下几种方式实现:
请尝试以下操作:在并行循环中执行CPU密集型计算,并在循环后将allResults保存到数据库中。