【发布时间】:2019-05-19 16:42:54
【问题描述】:
我有一个 .net 应用程序,它基本上每次(每 5 分钟)从数据库表中读取大约一百万条记录,进行一些处理并更新表,将记录标记为已处理。
目前,应用程序在单线程中运行,从 DB 表中获取前 4K 条记录,对其进行处理,更新记录,然后获取下一条。
我正在使用带有存储过程的 dapper。我正在使用 4K 记录进行检索以避免数据库表锁定。
在多个线程中检索记录并同时确保每个线程获得新的 4K 记录的最佳方法是什么?
我目前的想法是我首先只检索 1M 记录的 ID。按升序对 id 进行排序,并将它们分成 4K 批次,记住批次中的最低和最高 id。 然后在每个线程中,我将调用另一个存储过程,该过程将通过指定检索到的记录的最低和最高 id 来检索完整记录,然后进行处理等等。
有没有更好的模式我不知道?
【问题讨论】:
-
如果数据库访问本身是“基本的” - 即。是 I/O 绑定的,不能通过并发访问进行优化 - 从/到单个 DB 访问流可能“更好”。这可以允许,例如,单个排序/步行者。
-
此声明:“我正在使用 4K 记录进行检索以避免数据库表锁定。”这不是真的,这不是 DB Lock(假设 MS SQL Server)的工作方式,在您的实例中配置了您的 ISOLATION LEVEL 元素,您以哪种方式从该表中获取行等。有很多网络上有关它的信息,我的推荐:Kalen Delaney 博客和书籍以及 Paul Randall,两者都可以为您带来清晰的画面。
-
@GeovannyHernandez 本身不是为了阅读,但我跳过了有关更新记录部分的详细信息(这就是 4K 记录的原因)。使用包含需要标记为已处理的记录的所有 id 的 XML 参数调用存储过程。我记得读过 5K 是进行批量更新时表锁的限制。
-
@AlexDee,我知道这本身不是为了阅读,但我的意思是 MS SQL Server 已经准备好管理并发连接和 DML 操作,5K 的限制是第一次我听说,你不会把这个 5K 和 Lock scalation 混为一谈吗?
-
更好的模式是使用单线程读取数据库。
标签: c# .net sql-server multithreading design-patterns