SQL Server Service Broker-改进SQL执行框架的方法 服务代理设计处理查询

问题描述

下面是我一直在使用的Service Broker进行SQL执行框架设计的概述。我已经概述了过程,并提出了一些问题(使用引号突出显示),并且有兴趣听取有关设计的任何建议。

概述

我有一个ETL操作,需要从5个数据库中取出数据,然后使用select/insert语句或stored procedures将其移至150个数据库中。结果是大约2,000个独立查询,每个查询耗时1到1个小时。

每个SQL查询仅插入数据。无需返回数据。

该操作可以分为3个步骤:

  • ETL之前的
  • ETL
  • ETL后

每个步骤中的查询都可以按任意顺序执行,但是步骤必须保持顺序。

方法

我正在使用Service Broker进行异步/并行执行。

关于如何调整服务代理的任何建议(例如,要查看的任何特定选项或用于设置队列工作者数量的指南?

服务代理设计

启动器

initiator将包含SQL查询的XML消息与称为Unprocessed的激活存储过程一起发送到ProcessUnprocessedQueue队列。此过程包装在事务中的try/catch中,在出现异常时回滚事务。

ProcessUnpressedQueue

ProcessUnprocessedQueue将XML传递到过程ExecSql

ExecSql-SQL执行和记录

ExecSql然后处理SQL执行和日志记录:

  • XML和将要记录的有关执行的任何其他数据一起被解析
  • 在执行之前,将插入一个日志记录条目
    • 如果事务在initiator中启动,如果回退initiator中的外部事务,是否可以确保始终提交日志条目插入?

    • SAVE TRANSACTION之类的东西在这里无效,对吗?

    • 我应该不要在这里操作事务,在try/catch中执行查询,如果要进行捕获,则为异常插入日志条目,然后throw例外,因为它在交易中间?

  • 查询已执行
替代日志记录解决方案?

我需要登录:

  • 已执行的SQL查询
  • 有关操作的元数据
  • 每个过程完成所需的时间
    • 这就是为什么我在流程的开头插入一行,并在流程结束时插入一行
    • 的原因
  • 任何异常(如果存在)

最好有一个包含查询信息的In-Memory OLTP表?因此,我将在操作开始前一行INSERT,然后执行UPDATEINSERT来记录异常和执行时间。批处理完成后,我将数据存档到存储在磁盘中的表中,以防止表变得太大。

ProcessUnprocessedQueue-手动处理结果

执行后,ProcessUnprocessedQueue返回XML的更新版本(以确定执行是否成功,或有关事务的其他数据以进行后处理),然后发送该消息到ProcessedQueue没有没有激活过程,因此可以手动进行处理(我需要知道一批查询何时完成执行)。

处理查询

由于ETL可以分为3个步骤,因此我创建了3个XML变量,在其中添加了ETL操作所需的所有查询,因此我将得到以下内容:

  • @preEtlQueue xml
    • 200个查询
  • @etlQueue xml
    • 1500个查询
  • @postEtlQueue xml
    • 300个查询

为什么使用XML?

XML队列变量作为OUTPUT参数在不同的存储过程之间传递,该参数更新其值和/或向其添加SQL查询。该变量需要写入和读取,因此替代方案可以是诸如全局临时表或持久性表之类的东西。

然后我处理XML变量:

  • 使用cursor循环查询,并将其发送到服务代理服务。
    • XML变量中包含的每组查询都在同一conversation_group_id下发送。
    • 诸如“ to / from服务”,“消息类型”之类的值都存储在XML变量中。
  • 将消息发送到Service Broker之后,使用while循环连续检查ProcessedQueue,直到处理完所有消息为止。
    • 这实现了超时以避免无限循环
    • 我正在考虑重新设计它。我应该在ProcessedQueue上添加一个激活过程,然后使该过程将处理后的结果插入物理表中吗?如果这样做,将无法使用RECEIVE而不是WHILE循环来检查已处理的项目。那有什么缺点吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)