SQL Server服务经纪人:如何构建一个简单的队列情景对话?(Sql Server Servic

2019-08-01 01:02发布

我是一个SQL Server Service Broker的新手,我试图把握最好的方式来设置服务代理了一个(貌似)简单的例子:我想创建一个简单的工作队列,其中一个应用滴工作项目进入队列和单独的应用程序从队列中拿起工作项目并对其进行处理。 没有必要应用为先拿到状态消息从第二回。 我想队列生活在一个SQL Server实例。

什么最让我困惑的是如何对话/对话涉及到这种情况。 我知道你只能发送/在谈话/对话的上下文接收消息,但因为这两个应用程序之间没有回往复喋喋不休,我觉得失去了什么时候是正确的时间,以创建一个新的对话。 这两个极端的选择似乎是:

  • 每次我一入队的工作项目,我开始一个新的对话。 因此,每个会话结束有它正好一个消息。
  • 在部署的时候,我手动创建一个单一的无限寿命的谈话。 当它的时间来排队一个工作项目,我总是把它作为一个对话的一部分。

什么将要去这两种路线的后果是什么?

此外,在第一种情况下,好像我需要做一些结束对话,以便为SQL Server能够在内部清理资源。 是否有当将把这些在正确的位置的任何指导? (也可能是潜在更好地依靠对话最终超时?)

Answer 1:

你应该对自己的谈话每个工作项目启动。 生产者(引发剂)开始一个对话,并发送描述该工作项的消息,然后提交。 消费者(目标)接收消息(或被激活),检查有效载荷了解工作项目的详细信息,执行的工作,然后结束该对话和提交。 将所得的EndDialog消息被发送回到发起者服务队列中,并且在启动器队列的活化过程通过结束对引发剂侧的对话框响应它。

这是最简单的部署和得到它运行起来会确保你有一个良好的基础,以建立在。 不偷工减料,并最终从当制片人的入队的工作项目启动器方的对话,这是发射后不管和有几个抽奖背上 。

如果你有很高的性能要求(超过每秒200个请求),那么你就必须开始更明确地管理对话。 我有一个博客条目重复使用性能方面的原因的谈话 。 在接收端我建议你阅读写作服务代理程序 。

我也有一个博客条目,几乎做了你需要什么,尽管它并没有安排工作项目,而是推出一个自定义过程: 异步过程执行 。

如果您决定从激活的情况下消耗的工作项目,从而利用激活的漂亮自我平衡的能力,那么你需要了解EXECUTE AS根据该激活发生背景 。



Answer 2:

我真的很喜欢Remus的答案,尽管它没有特别的原因 ,你可能更愿意开始每个工作项目的单独谈话,而不是将所有工作项目在一个单一的谈话触及。 与此相关的有两点需要注意:

首先,将所有工作项目到一个会话可能会导致并发的问题,如果你有多个线程/进程处理的工作项目。 服务代理工作进程往往是这样的(伪代码):

begin transaction
receive top n work items from queue
process work items
commit transaction

(如果不承诺,直到工作项目成功处理,可以确保,例如,如果你的进程,然后死了,已收到但工作项目尚未处理将不会从队列中删除。)

因为服务代理被编程以使得每个接收命令获取关于作为中接收到的那些共享同一会话(或会话组)在队列中的所有消息的专用读锁就会出现并发问题。 这锁一直保持到事务被提交。 (见会话组锁 。)所以,如果队列中的所有工作项目都在一个单一的谈话,然后在一个工作进程中的“过程的工作项目”的步骤,没有其他工作进程可以做任何工作。

与把很多项目到一个会话的第二个问题是,它增加了你可能会失去,或者在某些错误情况下重新处理工作项目的数量。 为了描述正确我推迟到莱姆斯; 看到他回收的对话 ,特别是说,部分“重用一个对话框发送的所有邮件[...]就像把所有的鸡蛋放在一个篮子里。” 你也许可以从其中的一些错误情况恢复,但它可能会引入更多的复杂性,以你的代码。

有要对使用的所有工作项目单个对话可能做出一些更多的争论,但我不熟悉他们。

这并不是说正确的解决方案总是开始单独谈话的每一个工作项目。 通过Remus的帖子看了之后,虽然,他的建议似乎声音; 每一个交谈工作项目启动,然后在需要时添加的复杂性。 (但可能是在任何情况下,你去把所有的信息在一个谈话的极端。)



文章来源: Sql Server Service Broker: How to structure Conversations for a simple queue scenario?