2

我写了以下一段代码:

public void BulkUpdateItems(List<Items> items)
        {
            var bulk = new BulkOperations();

            using (var trans = new TransactionScope())
            {
                using (SqlConnection conn = new SqlConnection(@"connstring"))
                {
                    bulk.Setup()
                    .ForCollection(items)
                    .WithTable("Items")
                    .AddColumn(x => x.QuantitySold)
                    .BulkUpdate()

                    .MatchTargetOn(x => x.ItemID)
                    .Commit(conn);

                }
                trans.Complete();
            }
        }

使用 SQLBulkTools 库...但是这里的问题是当我一次从多个线程运行此过程时,我在死锁上运行...

并且错误表明某个进程 ID 已死锁或类似的情况......

有没有其他方法可以有效地从多个线程批量更新 1 个表?

有人可以帮我吗?

4

3 回答 3

5

我对该 API 了解不多,但快速阅读建议您可以尝试一些事情。我会按照列出的顺序尝试它们。

  1. 使用较小的批处理大小,和/或将批处理超时设置得更高。这将使每个线程轮流。

  2. 使用临时表。这将允许线程独立工作。

  3. 设置选项以使用表锁。如果你锁定整个表,不同的线程将无法锁定不同的行,所以你不应该遇到任何死锁。

于 2017-06-14T21:21:35.303 回答
0

死锁消息来自 SQL Server - 这意味着您的一个连接正在等待被另一个锁定的资源,而第二个连接正在等待第一个连接的资源。

如果您尝试更新同一个表,您可能会遇到一个简单的 SQL 锁定问题,并且与 C# 没有任何关系。您需要更彻底地考虑在多个线程上进行批量更新的含义;它可能(取决于您正在更新的表的百分比)更好地在单个连接上执行此操作并使用队列样式的机制来消除各个调用的冲突。

于 2017-06-14T20:56:42.690 回答
-1

尝试

锁 { .... }

这将做的是,当一个进程正在执行花括号内的代码时,它将导致其他进程等待第一个进程完成。这样,一次只有一个进程会执行该块。

于 2017-06-14T20:48:52.257 回答