![]() |
1
26
您应该从每个工作项开始自己的对话。生产者(发起人)开始一个对话框并发送描述工作项的消息,然后提交。使用者(目标)接收消息(或被激活),检查有效负载以了解工作项详细信息,执行工作,然后结束对话框并提交。生成的enddialog消息将被发送回发起程序服务队列,并且发起程序队列上的激活过程将通过在发起程序端结束对话框来响应它。 这是最简单的部署,让它运行并确保你有一个良好的基础。当生产者将工作项排队时,不要拐弯并结束启动器端的对话,这是 fire-and-forget and has several draw backs . 如果您有高性能需求(每秒超过200个请求),那么您必须开始更明确地管理会话。我在上有一篇日志 reusing conversations for performance reasons . 在接收端,我建议阅读 Writing Service Broker Procedures . 我还有一个博客条目,它几乎可以满足您的需要,尽管它不安排工作项,而是启动一个自定义过程: Asynchronous procedure execution . 如果您决定从激活的上下文中使用工作项,从而利用激活的良好的自我平衡能力,那么您需要 understand the EXECUTE AS context under which activation occurs . |
![]() |
2
9
我真的很喜欢雷姆斯的回答,尽管它没有特别的意义 为什么? 您可能更喜欢针对每个工作项启动单独的对话,而不是将所有工作项放在单个对话中。与此相关的两个注释: 首先,如果您有多个线程/进程处理工作项,将所有工作项放入一个会话中可能会导致并发问题。ServiceBroker工作进程通常如下所示(在伪代码中):
(通过在成功处理工作项之前不提交,您可以确保,例如,如果您的进程死亡,那么它收到但尚未处理的工作项不会从队列中删除。) 并发性问题会出现,因为ServiceBroker被编程为每个接收命令都获得队列中与接收到的消息共享相同会话(或会话组)的所有消息的独占读取锁。该锁一直保持到提交事务为止。(见 Conversation Group Locks 因此,如果队列中的所有工作项都在单个会话中,那么当一个工作进程处于“处理工作项”步骤时,其他任何工作进程都不能执行任何工作。 将大量项目放入单个会话的第二个问题是,它会增加在某些错误条件下可能丢失或必须重新处理的工作项目的数量。为了恰当地描述这一点,我遵从雷姆斯的说法;见他的 Recycling Conversations 尤其是“重用一个对话框来发送所有消息[…]就像把所有鸡蛋放在一个篮子里。”您可能能够从这些错误情况中恢复过来,但这可能会给您的代码带来更多的复杂性。 可能还有更多的理由反对对所有工作项使用单独的对话,但我对它们不太熟悉。 这并不是说正确的解决方案总是为每个工作项单独开始一次对话。不过,在阅读了雷姆斯的文章之后,他的建议似乎是合理的;从每个对话的一个工作项目开始,然后根据需要增加复杂性。(但在任何情况下,你都不应该极端地把所有的信息放在一次谈话中。) |