我们正在将.NET API用于IBM的WebSphere MQ。
创建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()似乎是客户端的廉价操作。
答案 0 :(得分:0)
答案取决于您的线程模型和事务性。通常,消息传递客户端应始终使用事务性,即使这只是单阶段提交。原因是结果含糊不清,否则可能导致重复或丢失的消息。我已经对此in another answer提供了更详细的解释。
问题是事务是连接范围的。当您执行COMMIT时,您将执行整个连接。安全地跨多个线程使用相同的连接将排除事务的使用,从而使应用程序暴露丢失或重复的消息。由于队列句柄仅在特定连接的上下文中有效,因此它们从您的线程模型和连接池继承。
服务提供者应用程序最常见的模型是在输入队列上维护每个线程的连接并动态打开/放置/关闭输出队列。例如,在一个工作单元中......
在这种情况下,不会不断重建连接,也不会关闭输入队列。但是,它确实需要每个线程保持专用连接。