Sql*_*yan 3 sql-server queue multithreading
我有一个SQL Server表,其中包含我的程序需要"跟进"的订单(调用web服务以查看是否已完成某些操作).我的应用程序是多线程的,可以在多个服务器上运行实例.目前,每隔一段时间(在线程计时器上),该过程ORDER BY NEWID()从"未确认"订单列表中随机选择100行并检查它们,标记任何成功返回的行.
问题是线程之间以及不同进程之间存在很多重叠,并且它们无法保证很快就会检查新订单.此外,一些订单永远不会被"确认"并且已经死亡,这意味着它们会妨碍需要确认的订单,如果我一遍又一遍地选择它们,会减慢流程.
我更喜欢的是系统地检查所有未完成的订单.我可以想到两个简单的方法:
我还缺少其他任何想法吗?这甚至有意义吗?如果我需要澄清,请告诉我.
结果:
我最终做的是在我的表中添加一个LastCheckedForConfirmation列,其中包含已完成的订单,我添加了一个存储过程,使用GETDATE()更新单个未确认的行并踢出订单号,以便我的进程可以检查它.它尽可能多地旋转(假设进程愿意运行的线程数),并使用存储过程为每个线程获取新的OrderNumber.
要处理"不要尝试行太多次或太旧时"的问题,我这样做了:如果"自上次尝试以来的时间">"创建和上次尝试之间的时间",SP将只返回一行,因此,每次再次尝试之前需要两倍的时间 - 首先等待5秒,然后是10秒,然后是20,40,80,120,然后在尝试15次(6小时)后,它会放弃该命令SP永远不会再回来了.
感谢大家的帮助 - 我知道我这样做的方式并不理想,我很欣赏你指点正确的方向.
我建议读取并内化使用表作为队列.
如果将数据用作队列,则必须正确组织数据以进行排队操作.我链接的文章详细介绍了如何执行此操作,您拥有的是Pending Queue的变体.
你必须绝对摆脱的一件事是随机性.如果在查询中有一件事难以重现,那就是随机性.ORDER BY NEWID()将扫描每一行,生成一个guid,然后排序,然后返回前100名.在任何情况下,您不能每次都有每个工作线程扫描整个表,随着未处理条目数量的增加,您将终止服务器.
而是使用待处理的日期.通过处理日期列(当项目需要重试时)组织(聚集)队列,并使用我在链接文章中显示的技术出列队列.如果要重试,则出列应该推迟项目而不是删除它,即.WITH (...) UPDATE SET due_date = dateadd(day, 1, getutcdate()) ...