.net 重用IBM.WMQ.MQQueue对象

.net 重用IBM.WMQ.MQQueue对象,.net,ibm-mq,.net,Ibm Mq,我们将.NETAPI用于IBM的WebSphere MQ 创建MQQueueManager对象显然是一项昂贵的操作,因此我们缓存并重用这些对象的池 目前,对于每个请求,我们都会访问所需的队列: //obtain queueManager from pool IBM.WMQ.MQQueue requestQ= queueManager.AccessQueue(requestQName, mqOptions); IBM.WMQ.MQQueue responseQ= queueManager.Acce

我们将.NETAPI用于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()在客户端上似乎是一种便宜的操作。

答案取决于线程模型和事务性。通常,消息传递客户端应该始终使用事务性,即使这只是单阶段提交。原因是,结果的模糊性可能导致重复或丢失消息。我已经对此做了更详细的解释

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

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

  • 阅读下一条请求消息
  • 使用回复信息获取目的地
  • 打开回复队列
  • 把答案写下来
  • 承诺
  • 销毁对目标对象的回复,从而关闭对队列的回复

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

    你说的“连接”是什么意思?我看到IBM文档也提到了它,但因为我认为我连接到了一个QueueManager,所以我真的不知道是否需要为每个线程创建一个新的QM(缓存它)。这个答案根本不涉及IBMs MQ实现——只要您这样做(至少)更不用说我否决了。谢谢你对否决票的解释。如果答案依赖于MQ特定的行为,我很乐意更新以指出这一点。然而,问题和答案都依赖于IBM的实现中符合JMS规范并且可以在该上下文中有效描述的行为。你当然可以反对这种做法,我感谢你的解释,但我对书面答复感到满意。