我目前正在使用带有SQL Server 2012 Service Broker的SqlDependency,我希望能够配置两个服务器,同时监听服务代理并拉出队列,但只应将消息从队列中拉出一次。每台机器都应该尽量减少它所能提供的功能,但是如果有太多机器进入它应该分享一个平衡,以拉动它可以。现在我开始两个程序实例,两个都在听。添加新消息后,它们都会从队列中取出相同的消息并运行代码。
SqlDependency不是我想做的解决方案吗?对这样的事情有什么更好的解决方案?
答案 0 :(得分:2)
添加新消息后,他们都会从队列中取出相同的消息并运行代码
您描述的行为是SQLDependency的工作方式。如果有多个侦听器,则通知所有侦听器。例如,您可以在SignalR SQL Backplane documentation
中看到这一点注意所有虚拟机如何从SQL Server接收通知,包括发起更新的虚拟机。
如果要跨工作虚拟机池分发SQL通知,则需要一种共享状态的方法。请注意,SQL通知仅表示 某些内容已更改,并且未指示更改。一种方法是将表添加到数据库以充当作业或操作的队列。订阅者可以在每个通知上查询此队列,并通过更新或删除此表来声明操作。 (必须在桌面上配置适当的锁)
或者,您可以使用其他共享状态工具执行此操作,例如消息队列(例如RabbitMQ)或分布式缓存(例如Redis)
答案 1 :(得分:1)
您不需要SQL Notifications或SQLDependency。每个实例都可以执行:
WAITFOR(
RECEIVE TOP(1) * FROM {NameOfQueue}
), TIMEOUT @timeoutvalue;
此命令将等待,保持连接打开,直到消息可用或发生超时。在超时时,您不会收到任何消息,因此只需连接并重试。
每条消息只能由一个进程接收。在内部,Server Broker队列中的行被锁定,其他读者将 READPAST 锁定行。
因为SQL可能有点棘手,所以我写了一些我觉得有用的wrapper class that you are free to use。