我有一个SSBS队列,主进程发送M
个消息到队列。有N
个子进程逐个获取消息并处理它们。处理完所有消息后,子进程将退出。现在我正在做以下事情,
方法1:
主要进程在发送N
消息后发送M
“EndOfData”。但是它不能很好地工作,因为一些子进程可能会收到多个“EndOfData”消息,因此某些子进程永远不会收到消息。
方法2 :(扩展方法1)
为每个子流程分配一个ID,同时在“EndOfData”消息中嵌入一个ID。如果消息中的ID与其ID不匹配,则子进程回滚。但是,它会导致“poise message”问题,因为回滚太多而队列被禁用。
begin tran
begin try
WAITFOR(
RECEIVE TOP(1)
@MessageType = message_type_name,
@MessageBody = CAST(message_body AS xml)
FROM
TargetQueue
) , TIMEOUT 1000
if @MessageType = 'EndOfData' and
@MessageBody.value('(//ID/text())[1]', 'int') <> @ID
BEGIN
rollback tran
waitfor delay '00:00:02'
END
有没有一种好方法可以实现它?
更新
子流程将执行以下步骤。
https://..../EndDialog
并退出https://.../EndDialog
条消息,则只需接收答案 0 :(得分:1)
另一种方法,假设N = 3
:
3
的“EndOfData”类型的消息。2
的响应消息,退出。所以剩下2个正在运行的子流程。2
接收回复,并发送包含2
的“EndOfData”类型的消息。1
的响应消息,退出。所以剩下1个正在运行的子流程。1
接收回复,并发送包含1
的“EndOfData”类型的消息。0
的响应消息,退出。没有正在运行的子流程。0
接收回复,并停止发送“EndOfData”类型的消息。答案 1 :(得分:0)
使用以下代码并将工作放在事务中。因此,脚本块可以在收到EndOfData
消息后退出。
$conn = new-object Microsoft.SqlServer.Management.Common.ServerConnection
$conn.DatabaseName = "..."
$conn.BeginTransaction()
$conn.ExecuteNonQuery("Receive message;")
# do work
$conn.CommitTransaction()