我正在处理一个涉及处理大量文本文件并导致将记录插入到mssql数据库或更新现有信息的项目。并行处理多个sql语句导致死锁
sql语句被写入并存储在一个列表中,直到文件完成处理。 然后处理该列表。每条语句都是一次处理一条语句,但这可能会导致数千条语句,并且可能会创建一个长时间运行的流程。
要尝试加快这个过程中,我介绍了一些并行处理,但这种偶尔会导致以下错误:
Transaction (Process ID 94) was deadlocked on lock | communication buffer resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
代码如下:
public static void ParallelNonScalarExecution(List<string> Statements, string conn)
{
ParallelOptions po = new ParallelOptions();
po.MaxDegreeOfParallelism = 8;
CancellationTokenSource cancelToken = new CancellationTokenSource();
po.CancellationToken = cancelToken.Token;
Parallel.ForEach(Statements, po, Statement =>
{
using (SqlConnection mySqlConnection = new SqlConnection(conn))
{
mySqlConnection.Open();
using (SqlCommand mySqlCommand = new SqlCommand(Statement, mySqlConnection))
{
mySqlCommand.CommandTimeout = Timeout;
mySqlCommand.ExecuteScalar();
}
}
});
}
更新语句我认为很简单在他们试图实现什么:
UPDATE TableA SET Notes = 'blahblahblah' WHERE Code = 1
UPDATE TableA SET Notes = 'blahblahblah', Date = '2016-01-01' WHERE Code = 2
UPDATE TableA SET Notes = 'blahblahblah' WHERE Code = 3
UPDATE TableA SET Notes = 'blahblahblah' WHERE Code = 4
UPDATE TableB SET Type = 1 WHERE Code = 100
UPDATE TableA SET Notes = 'blahblahblah', Date = '2016-01-01' WHERE Code = 5
UPDATE TableB SET Type = 1 WHERE Code = 101
什么解决这个问题的最好方法是什么?
用'profiler'捕获死锁图。而这个sql代码演示了单个更新语句还是这个并行单行语句执行的列表? –
也许你应该重新设计你在做什么。看起来你正在创建一个语句列表,然后试图执行它们,每个语句打开一个新的连接?你为什么想这么做。将文本文件加载到SQL服务器上的临时表中,然后执行简单的服务器端插入/更新(可能是单个插入和单个更新)可能会更容易,更快速。 –
@CetinBasoz我相信我需要每个线程一个连接。我以前打开过一个连接,但遇到了如下所述的命令问题:[link](http://stackoverflow.com/questions/18475195/error-there-is-already-an-open-datareader-associated-with -this-command-which-mu) – AdamB