2

部分服务由第三方提供给我们的客户。在其远程服务器上创建的数据被复制到本地 SQL 服务器。我需要在我无法直接访问该数据库的第 3 方服务器上执行一些工作。他们为此目的公开了一组 API。该工作由 SQL Server 代理作业在链接的 SQL 服务器上执行。

业务场景:客户可以收到“徽章”。可以通过调用UpdateCustomerBadgeInfo3rd方服务器上的web方法给客户一个徽章。

因此,自动化任务的典型要求如下所示:

“找到所有白天登录超过 50 次的客户,给他们[has-no-life]徽章并给他们发送短信通知”

该算法将是:

- Select all the matching accounts into a #TempTable  
 for each customer record:
 - Call UpdateCustomerBadgeInfo() method (via CLR)
 - If successfully updated badge info-> Enqueue SMS message (queue table)
 - Log successful actions (so that the record will not be picked up next time)

它现在工作方式的最大问题是在 WHILE 循环中处理大型数据集需要大量时间。

因此,第 3 方提供商创建了一个解决方案来执行客户数据的批量更新。他们在本地 SQL 服务器上创建了一个表,批量更新请求被提交到该表,然后由他们的服务获取以进行验证和处理。

问题是 :

应如何更改上述算法以适应此异步模型?

4

1 回答 1

2

仅当我正确理解情况时,此答案才有效:

  • 3rd 方服务器用于暴露 web 方法来一一更新客户
  • 现在他们希望从 SQL Server 表中获取此信息,以便您进行 INSERT/UPDATE/DELETE
  • 您可以将与客户相关的请求填充到此表中,稍后将对其进行处理
  • 当客户相关信息更新时,您必须执行一些额外的本地操作(队列短信、日志活动)

一般来说,我看不到算法有任何重大变化,但我会尝试解释在这种情况下我会做什么。

  1. 选择所有匹配的帐户到#TempTable

    这可能不是必需的,因为您已经有表格可以将您的请求放入 - 第 3 方表格。唯一的问题是同步请求,但要对此进行分析,您必须提供更多详细信息(允许同一客户的多个请求?保护重新发出相同请求?)

  2. 对于每个客户记录...

    这应该是您的实施中的唯一更改。它现在具有意义 -对于在 3rd 方异步处理的每个客户记录。当然,您的第 3 方必须给您一些线索,表明他们确实处理了您的客户请求,否则您不知道该使用什么。因此,当他们验证和处理数据时,他们可以提供例如可以为空的列“success_time”和“error_time”,以便向您发送已完成的内容和时间信息。如果成功,则继续处理。如果没有,您可能也可以对此做一些事情。

    但是当你得到异步信息时如何反应(例如 sucess_time IS NOT NULL)?好吧,有多种方法可以做到这一点。就我个人而言,我尽量避免触发,因为它们会使你的生活变得复杂(它们的可见性很差,可能导致复制问题,可能导致事务问题......)如果我真的需要一流的即时响应能力,我会使用它们。另一种可能性是使用带有自定义激活的异步队列,这意味着Service Broker。然而,很多人避免使用 SB 技术——它与 SQL 服务器的其他部分不同,它有其特殊性,调试不像使用普通的旧 SQL 语句等那样容易。另一种可能性是在你这边批处理异步响应使用代理工作. 由于您已经在使用工作,因此应该没问题。基本上,该表应充当同步点 - 您填写您的请求 (INSERT),第 3 方处理它们 (SELECT)。处理请求后,他们将它们标记为此类(更新成功时间或错误时间),最后您使用代理作业任务处理该响应(SELECT)。您的处理包括 SMS 消息和日志记录,甚至可能从 3rd 方表中删除。

    还有一点要提的是,这里需要同步方法。首先,不要在没有事务的情况下做任何事情,否则您最终可能会处理幽灵响应和/或跳过有效的等待响应。其次,当您选择响应(在第 3 方处理的行)时,您可以使用 READPAST 提示获得一些改进(跳过锁定的内容)。但是,如果您需要在处理响应后从 3rd 方表中更新/删除,您可以使用 SELECT 和 UPDLOCK 来阻止 tempig 的另一侧,其中包含 INSERT 和 UPDATE 之间的数据。或者,如果您不完全确定所讨论的表发生了什么,则不使用任何锁定提示。

希望能帮助到你。

于 2013-07-06T23:56:40.887 回答