cod*_*net 10 .net c# sql-server multithreading sql-server-2008
我有一个运行多线程的进程.
Process具有要处理的项的线程安全集合.
每个线程在循环中处理集合中的项.
列表中的每个项目都由线程发送到存储过程,以将数据插入到事务中的3个表中(在sql中).如果一个插入失败,则所有三个都失败.请注意,交易范围是每个项目.
插入非常简单,只需将一行(相关的外键)插入每个表中,并使用标识种子.没有读取,只需插入然后继续下一个项目.
如果我有多个线程试图处理他们自己的项目,每个项目都试图插入到同一组表中,这会因为事务锁定而产生死锁,超时或任何其他问题吗?
我知道每个线程必须使用一个数据库连接,我主要关注每个事务中表的锁级别.当一个线程将行插入3个表时,其他线程是否必须等待?除了自动标识需要递增之外,每个表没有行的依赖性.如果它是一个表级锁定来增加标识,那么我想其他线程将不得不等待.插入物有时可能很快或者可能不快.如果它必须等待,多线程是否有意义?
多线程的目标是加速项目的处理.
请分享您的经验.
PS:身份种子不是GUID.
在SQL Server中,多个插入到单个表中通常不会自行阻塞.IDENTITY生成机制是高度并发的,因此它不会序列化访问.如果插入在唯一索引中插入相同的键,则插入可能会相互阻塞(如果两者都尝试提交,则其中一个也会遇到重复的键冲突).你也有一个概率游戏,因为密钥被散列,但它只在大型交易中发挥作用,参见%% LOCKRES %% COLLISION PROBABILITY MAGIC MARKER:16,777,215.如果事务插入到多个表中也不应该存在冲突,只要再次插入的键是不相交的(如果插入是master-child-child,这自然会发生).
话虽如此,二级索引的存在以及特别是外键约束可能会引入阻塞和可能的死锁.没有确切的模式定义是不可能告诉你是否或不容易死锁.任何其他工作负载(报告,读取,维护)也会增加争用问题,并可能导致阻塞和死锁.
真正非常高端的部署(不需要在论坛上寻求建议的那种......)可能会受到插入热点症状的影响,请参阅解决高度并发的INSERT工作负载上的PAGELATCH争用
顺便说一句,从多个线程执行INSERT很少是提高负载吞吐量的正确答案.有关如何解决该问题的建议,请参阅"数据加载性能指南".最后一条建议:多线程也很少能让任何程序更快.异步编程几乎总是正确的答案.见和.AsynchronousProcessingBeginExecuteNonQuery
作为旁注:
只需在每个表中插入一行(外键相关),...没有读,
这种说法实际上是矛盾的.外键意味着读取,因为它们必须在写入期间进行验证.