Deadlock in Parallel.Foreach while using ExecuteNonQuery?

梦想的初衷 提交于 2020-05-17 03:01:34

问题


I am facing deadlock error while using Parallel.Foreach. I have 1000 records in datatable and i'hv created 5 threads to process it. but when i'hv run this console application then after some records processed it will create a deadlock and no other records will process. Here is my code :

Parallel.ForEach(dt1.AsEnumerable(), new ParallelOptions { MaxDegreeOfParallelism = 5 }, dr =>
{
    cmd1.CommandText = $"Update AuditMessage set Status=1" +
        $" where SXAEASCoreAuditMessageID ='{Convert.ToString(dr["AuditMessageID"])}' ";
    cmd1.CommandType = CommandType.Text;
    cmd1.Transaction = trans;
    cmd1.ExecuteNonQuery();                          
});

回答1:


Why does it lock?

Your problem is probably not database concurrency, but concurrency on the cmd1 object, which you are using for every thread.

You need to create a new SqlCommand for each of the threads, or in every iteration.

Parallel.ForEach(dt1.AsEnumerable(), new ParallelOptions { MaxDegreeOfParallelism = 5 }, dr =>
    {
                  using(var cmd = new SqlCommand(connection))
                  {
                     cmd.CommandText = $"Update AuditMessage set Status=1 where SXAEASCoreAuditMessageID ='{Convert.ToString(dr["AuditMessageID"])}' ";
                     cmd.CommandType = CommandType.Text;
                     cmd.Transaction = trans;
                     cmd.ExecuteNonQuery();
                  }                          
    });

some basics on row/table locking.

In case you are doing is on SQL Server, you are creating more overhead than speed out of this parallel processing. Every row modified will be locked by the DBMS, and eventually, when the overhead gets to high, it will commence a table lock, leaving your threads working sequentially anyway.

so, forget about parallel.foreach here, and let the database do the efficiency optimizing

You could select the AuditMessageIds into a List. Then cut it to pieces of 100 or so, and then make a smarter update query, like a query which does the update to status 1 in bulks..

where SXAEASCoreAuditMessageID IN ...


来源:https://stackoverflow.com/questions/61673300/deadlock-in-parallel-foreach-while-using-executenonquery

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!