问题描述
下面是我一直在使用的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
中,在出现异常时回滚事务。
ProcessUnprocessedQueue
将XML传递到过程ExecSql
ExecSql
然后处理SQL执行和日志记录:
-
XML
和将要记录的有关执行的任何其他数据一起被解析 - 在执行之前,将插入一个日志记录条目
-
如果事务在
initiator
中启动,如果回退initiator
中的外部事务,是否可以确保始终提交日志条目插入? -
像
SAVE TRANSACTION
之类的东西在这里无效,对吗? -
我应该不要在这里操作事务,在
try/catch
中执行查询,如果要进行捕获,则为异常插入日志条目,然后throw
例外,因为它在交易中间?
-
- 查询已执行
我需要登录:
- 已执行的SQL查询
- 有关操作的元数据
- 每个过程完成所需的时间
- 这就是为什么我在流程的开头插入一行,并在流程结束时插入一行 的原因
- 任何异常(如果存在)
最好有一个包含查询信息的In-Memory OLTP
表?因此,我将在操作开始前一行INSERT
,然后执行UPDATE
或INSERT
来记录异常和执行时间。批处理完成后,我将数据存档到存储在磁盘中的表中,以防止表变得太大。
执行后,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 (将#修改为@)