代码之家  ›  专栏  ›  技术社区  ›  Spence

如果队列管理器不可用并且使用了事务,MQQueueManager构造函数将挂起

  •  1
  • Spence  · 技术社区  · 14 年前

    我有一个问题,如果队列管理器关闭,MQQueueManager构造函数的调用将挂起。

    当我调用MQQueueManager的构造函数时,我打开了一个带有EnterpriseOptions.Full的TransactionScope。如果MQ已关闭(或者可能在QM关闭时尝试连接),则此调用将挂起。即使事务过期,也不会在事务中引发超时异常。

    因此,如果MQ可以关闭(它可以…),那么在建立连接时如何阻止队列挂起。我正在使用mq6.0.2.5中的托管客户端。

    我添加了一些代码以使问题更清楚:

    TransactionOptions opt = new TransactionOptions();
    opt.IsolationLevel = IsolationLevel.Serializable;
    opt.Timeout = new TimeSpan(0, 0, 20);
    TransactionScopeOption ScopeOption = TransactionScopeOption.Required;
    
    using (TransactionScope tran = 
        new TransactionScope
            (ScopeOption, 
            opt, 
            EnterpriseServicesInteropOption.Full))
    {
        //This line hangs if MQ is down, doesn't backout or throw a 2059.
        var m_qMgr = new MQQueueManager(QueueManager, Channel, Hostname);
        tran.Complete();
    }
    
    2 回复  |  直到 14 年前
        1
  •  1
  •   T.Rob    14 年前

    我认为有两种可能性。一个是它的级别低于WMQ,另一个是WMQ代码可能有一个未处理的异常。让我们看看这两个。

    假设TCP在尝试构建套接字时挂起,那么当WMQ启动而不是关闭时,它为什么会工作呢?一个答案是,如果在QMgr关闭后WMQ侦听器仍然处于打开状态。在这种情况下,侦听器接受套接字,但没有任何东西可以将其交给它。如果侦听器是用runmqlsr启动的,而不是作为QMgr侦听器对象启动的,则这是常见的。如果使用inetd作为侦听器,这实际上是不可避免的。你没有在QMgr那边提到这个版本。WMQ的哪个版本以及侦听器是如何启动的?QMgr运行在哪个平台上?

    我考虑的第二种可能性是配置与选项不匹配。WMQ将对任何客户端安装执行一阶段提交,但您要求它做的是与Windows作为事务控制器进行协调。在客户机模式下,这需要扩展事务客户机(又称XTC)。XTC组件是WMQ服务器安装的一部分,实际上是作为WMQ服务器授权的。换句话说,如果您在Windows主机上为WMQ服务器付费,那么您就有权在那里安装完整的WMQ服务器和/或XTC组件。XTC组件提供mqic32xa.dll,该dll通过WMQ客户机连接提供XA事务性。

    很多时候,不知道许可含义的人会抓取XA dll或Java/jmsxa类并将它们放到WMQ客户机安装中。如果XA类不是使用WMQ服务器介质安装的,这可能会导致不可预知的结果,例如您看到的结果。如果XA支持文件和WMQ客户机安装处于不同的补丁包级别,或者更糟的是,处于不同的版本,则尤其如此。

    IZ54336 其内容为“在托管.NET应用程序尝试mqconn期间,在服务器上观察到AMQ9456协议错误,在客户端上观察到2018 hconn错误。”

    要为您的应用程序正确安装WMQ,禁止的方法是获取wmqv7.0服务器介质并从该介质安装wmqclient。为安装选择扩展事务客户机。完成后,应用最新的补丁包。.Net类已集成到v7中的WMQ基本产品中,并且完全受支持。使用服务器介质可以在安装客户机时提供XA支持。除了v7是一个更好的.Net实现之外,v6在12个月内就要过时了,所以现在使用v7可以避免以后的转换或失去支持。v7客户机与v6qmgr兼容,但您当然无法获得新的v7功能。

    您可以下载WMQ服务器试用版 http://bit.ly/WMQTrial
    您可以在下载最新的补丁包 http://bit.ly/WMQFixes

        2
  •  1
  •   MJ Richardson    14 年前

    例如

     // set up the connection settings for the queue manager.
     var settings = new Hashtable {{MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED}};
     var qm = new MQQueueManager("yourQueueManagerName", settings);
    

    你可以找到更多关于这个房产的信息 here