仅限MSMQ Peek权限(即没有接收权限)?

时间:2011-09-30 21:16:49

标签: c# msmq

摘要(tl; dr):我们正在尝试设置一个Peek访问但不是Receive访问权限的队列用于测试目的(所以{{1请求将失败,但Receive将成功),但似乎MSFT比预期更难。

后台:我们有一个本地私有MSMQ队列,一个进程从中接收并处理(/使用)消息。在某些情况下,无法完成处理并且消息保留在队列中(例如,转发目的地暂时离线)。因此,每隔约10分钟就会添加一个监视器以查看队列,并查看顶部的消息是否相同 - 如果消费者停止(同一消息位于顶部),监视器会触发警报以指示那是错的。

为了测试目的强制队列停止(为了确保监视器功能正常工作),我们认为我们只是从队列中删除(但不是拒绝Peek权限本身但仍然允许 Receive(重新启动MSMQ以及强制执行新权限的所有内容),理想情况下,监视器允许Peek消息,而不允许任何人Peek (/删除)消息,“拖延”队列并生成警报。

然而,在测试这个场景时,我遇到了一个异常,似乎阻止了这种方法:

Receive

这表明(至少对我来说)System.Messaging.MessageQueueException: Access to Message Queuing system is denied. at System.Messaging.MessageQueue.MQCacheableInfo.get_ReadHandle() at System.Messaging.MessageQueue.StaleSafeReceiveMessage(UInt32 timeout, Int32 action, MQPROPS properties, NativeOverlapped* overlapped, ReceiveCallback receiveCallback, CursorHandle cursorHandle, IntPtr transaction) at System.Messaging.MessageQueue.ReceiveCurrent(TimeSpan timeout, Int32 action, CursorHandle cursor, MessagePropertyFilter filter, MessageQueueTransaction internalTransaction, MessageQueueTransactionType transactionType) at System.Messaging.MessageQueue.Peek(TimeSpan timeout) 内部调用Peek()并且必须尝试事务ReceiveCurrent(),然后它将在完成消息后回滚/中止。启动.NET Reflector,我发现Receive的所有实例都调用Peek的某个变体,因此不同的Receive无效。因此,对于Peek来说,Receive权限似乎是必需,就队列设计而言似乎有些愚蠢。

请注意,使用者和监视器都使用相同的帐户(/ permissions),并且此时更改监视方法(使用Peek)不是一个可行的选项(因为需要对要求,规格和生产代码进行重大更改,而这些更改的成本将超过其价值)(尽管我猜你可以提出监控方法的变化,如果你真的必须这样做,因为如果他们遇到同样的事情他们可能对他人有用)。

最后,问题:在没有Peek权限的情况下,队列顶部的Peek是否有更好的(甚至是不同的:p)方式?或者以不同的方式设置权限(通过权限界面,通过代码等),使Receive本身失败但ReceiveReceiveCurrent所需的其他方法有效?

0 个答案:

没有答案