【发布时间】:2017-10-19 08:48:49
【问题描述】:
我遇到了一段代码,其中我在 Parallel Loop 中看到了一些数据库调用。所以,我想到的问题是数据库调用是线程安全的,因为并行循环在多个线程中执行。
这是供您查看的一小段代码:
Parallel.ForEach(list, item =>
{
//this function update the user status by connecting with database
_IUserRepository.UpdateUserStatus(item.UserId, item.status);
});
每个线程是否并行循环,等待用户状态更新?
如果我们在以下列表中有记录会发生什么:
UserId, Status
1,0
1,1
1,0
1,1
- id=1 的用户的最终状态是什么?
- 这里是否存在死锁或竞争条件的可能性?
谢谢!
【问题讨论】:
-
未知代码的线程安全是不可能的。 性能 虽然可能会受到很大影响,因为多个连接竞争相同的资源。如果您有性能问题,问题出在代码本身,不会随着并行化而改善。
-
例如,如果您只执行单行更新,那么每次更新所花费的时间几乎有 80% 是网络流量。如果将 100 个更新一起批处理,或者将值作为表值参数传递,则可以将性能提高近 80 倍。更好的是,使用 SqlBulkCopy 将更改推送到临时表并在服务器上执行单个 UPDATE。 SqlBulkCopy 使用最少的日志记录和锁定 - 它不是记录每一行,而是记录整个页面。使用临时表,您也不会遇到任何锁定问题。
-
更多普通问题 - 如果
UserID不是索引的第一列,则每次 UPDATE 都会导致全表扫描。索引它和性能将增加几个数量级 -
@PanagiotisKanavos,感谢您提供详细信息 cmets。这对我很有帮助。
-
为什么用“sql-server”标记?
标签: c# sql-server multithreading parallel-processing