【问题标题】:Reusing IBM.WMQ.MQQueue object重用 IBM.WMQ.MQQueue 对象
【发布时间】:2011-05-22 13:55:48
【问题描述】:

我们正在使用 IBM 的 WebSphere MQ 的 .NET API。

创建 MQQueueManager 对象显然是一项昂贵的操作,因此我们缓存并重用这些对象的池。

目前,对于每个请求,我们都会访问所需的队列:

//obtain queueManager from pool
IBM.WMQ.MQQueue requestQ= queueManager.AccessQueue(requestQName, mqOptions);
IBM.WMQ.MQQueue responseQ= queueManager.AccessQueue(responseQName, mqOptions);

完成后关闭它们:

requestQ.Close();
responseQ.Close();

这是最佳实践,还是我们也应该池化和重用 MQQueue 对象(除了队列管理器)? AccessQueue() 似乎是客户端上的廉价操作。

【问题讨论】:

    标签: .net ibm-mq


    【解决方案1】:

    答案取决于您的线程模型和事务性。一般来说,消息传递客户端应该始终使用事务性,即使这只是单阶段提交。原因是结果不明确,否则可能导致重复或丢失消息。我已经对此in another answer 提供了更详细的解释。

    问题是事务是连接范围的。当您提交时,您会为整个连接执行此操作。跨多个线程安全地使用相同的连接将排除事务的使用,从而使应用程序暴露于丢失或重复的消息。由于队列句柄仅在特定连接的上下文中有效,因此它们继承自您的线程模型和连接池。

    服务提供者应用程序最常见的模型是在输入队列上维护每个线程的连接,并动态打开/放置/关闭输出队列。例如,在单个工作单元中...

    1. 阅读下一条请求消息
    2. 使用回复信息获取目的地
    3. 打开回复队列
    4. 回复
    5. 提交
    6. 销毁回复目标对象,从而关闭回复队列

    在这种情况下,连接不会不断重建,输入队列也不会关闭。但是,它确实需要每个线程维护一个专用连接。

    【讨论】:

    • 你说“连接”,你是什么意思?我看到 IBM 文档也提到了它,但由于我认为我 connected 到 QueueManager,我真的不明白我是否需要为每个线程创建一个新的 QM(缓存它)与否。
    • 这个答案根本不涉及 IBM 的 MQ 实现——只要你(至少)不提我投票否决。
    • 感谢您对否决票的解释。如果答案依赖于 MQ 特定的行为,我会很乐意更新以指出这一点。然而,问题和答案都依赖于 IBM 实现中符合 JMS 规范并且可以在该上下文中有效描述的行为。您当然可以对这种方法提出异议,我很欣赏这种解释,但我对所写的回复感到满意。
    猜你喜欢
    • 2017-07-02
    • 2010-09-28
    • 2010-10-25
    • 2017-09-21
    • 2012-04-13
    • 2015-03-09
    • 1970-01-01
    • 1970-01-01
    • 2014-03-20
    相关资源
    最近更新 更多