异步处理事务性 WCF MSMQ 部分排序消息
我尝试过 MsmqIntergrationBinding 和 NetMsmqBinding,但我正在努力实现异步处理事务性 WCF MSMQ 部分排序消息的目标。
我想使用 WCF 来侦听事务队列上的消息。为了处理消息,我根据消息内容将传入消息解复用到各种(内存中)队列中。在异步处理消息时,MSMQ 事务保持打开状态,但 WCF 调度程序可以自由地继续接受任何下一条消息。队列中的多路分解消息需要包含在完全处理后提交或回滚 MSMQ 事务所需的句柄。对 Process() 的 WCF 回调完成后,MSMQ 不应等待异步消息被处理,也不应在异步操作完成之前提交事务。消息在“对话”内具有部分排序,当将其从MSMQ读入队列时应当保留该部分排序。
障碍是我无法弄清楚如何在不阻止 WCF 的情况下保持事务打开,并且我无法弄清楚如何在没有单线程 WCF 的情况下维护部分排序。如果我可以维护事务,但释放单线程 WCF 调度程序以继续下一个 msmq.Receive(),一旦我只是将内存中的项目排队(及其打开的事务),我想我'会没事的。
我尝试过将 TransactionAutoComplete = false,但这会产生一系列令人讨厌的后果,包括强制 InstanceContextMode = PerSession,因此只需要 NetMsmqBinding,与 MsmqIntegrationBinding 相比,我不喜欢 NetMsmqBinding。另外,除非在 Process() 操作上设置 IsTerminate = true,否则我根本无法提交事务。无论如何,PerSession 似乎是一个不合适的选择。但我仍然失败:如果我尝试将 operationContext = OperationContext.Current
传递给异步处理,它似乎会丢失一些重要的内部结构,因为当我尝试 operationContext.SetTransactionComplete 时出现错误();
表示没有事务需要完成。
[OperationContract(IsOneWay = true, Action = "*", IsTerminating = true)]
void Process(M msg);
我可以线程等待 WCF 的 Process() 调用,直到异步操作发出信号表明它们已完成,但这实际上需要多线程 WCF 并消除部分排序要求。
有想法吗?
I've tried MsmqIntergrationBinding and NetMsmqBinding, but I'm struggling to achieve my goal of processing transactional WCF MSMQ partially-ordered messages asynchronously.
I want to use WCF to listen for messages on a transactional queue. To process the message, I demultiplex the incoming message into various (in-memory) Queue<>s based on message contents. The MSMQ Transaction stays open while the message is processed asynchronously but the WCF Dispatcher is free to move ahead with accepting any next message. The Queue<>'d, demultiplexed messages need to contain the handles necessary to commit or rollback the MSMQ Transaction once fully processed. The completion of the WCF callback to Process() the MSMQ should not wait for the asynchronous message to be processed nor should it Commit the transaction before the asynchronous operations are finished. The messages have a partial ordering within "conversations" which should be preserved as it is read from the MSMQ into the Queue<>.
The obstacle is that I cannot figure out how to keep the transaction open without holding up WCF, and I can't figure out how to maintain the partial ordering without single-threading WCF. If I can maintain the transaction but release a single-threaded WCF dispatcher to move on the the next msmq.Receive() once I've merely Queue<>'d the item in memory (with it's open transaction) I think I'd be OK.
I've tried turning TransactionAutoComplete = false, but that had a nasty chain of consequences, including forcing InstanceContextMode = PerSession and therefore requiring NetMsmqBinding only which I dislike compared to MsmqIntegrationBinding. Also, I cannot commit the transaction at all unless I have IsTerminating = true on the Process() operation. PerSession seems like an otherwise inappropriate choice anyhow. Yet I remain defeated: If I try to pass around the operationContext = OperationContext.Current
to the asynchronous processing, it seems to lose some important internals because I get errors when I try to operationContext.SetTransactionComplete();
saying there's no transaction to be completed.
[OperationContract(IsOneWay = true, Action = "*", IsTerminating = true)]
void Process(M msg);
I could thread-wait the Process() call by WCF until the async operations signal that they're complete, but that practically requires multi-threaded WCF and kills the partial-ordering requirement.
Ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是一个问题。
您正在专门处理队列。它是一种固有的有序结构,保证“先进先出”。您正在以事务方式处理它,这意味着如果发生回滚,则需要将消息放回到队列的头部。
在处理完第一条消息之前,如何处理队列中的第二条消息 - 如果回滚,会发生什么情况?
That's a problem.
You're specifically dealing with a queue. It's an inherently ordered structure which guarantees "first in, first out". You're dealing with it transactionally, which means that if there's a rollback then a message needs to be put back to the head of the queue.
How can you process a second message in the queue before you've finished with the first - what would happen in the case of a rollback?