其他分享
首页 > 其他分享> > 如何使用.net TransactionScope从MQ进行事务GET?

如何使用.net TransactionScope从MQ进行事务GET?

作者:互联网

我有一个.NET TransactionScope,它需要同时包含MSSQL数据库和IBM MQ队列.

我在完全托管模式下使用.NET 4.0(VS2010),SQL 2008R2,MQ Server 6.0,MQ Client 7.0.1.9.所有组件都在不同的计算机上运行.

根据我的发现,以下模式应该有效:
http://publib.boulder.ibm.com/infocenter/wmqv7/v7r1/index.jsp?topic=%2Fcom.ibm.mq.doc%2Fun11400_.htm

Implicit Transaction
The following piece of code describes how a WebSphere MQ .NET application puts a message using .NET implicit transaction
programming.

Using (TransactionScope scope = new TransactionScope ()) { Q.Put
(putMsg,pmo); scope.Complete (); }

Q.close(); qMgr.Disconect();}

在我的代码中,这看起来像:

  // mq properties
  properties = new Hashtable();
  properties.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED);
  properties.Add(MQC.HOST_NAME_PROPERTY, HOSTNAME);
  properties.Add(MQC.PORT_PROPERTY, PORTNUMBER);
  properties.Add(MQC.CHANNEL_PROPERTY, CHANNELNAME);

  _queueManager = new MQQueueManager(queueManagerName, properties);
  _queue = _queueManager.AccessQueue(queueName, MQC.MQOO_INPUT_AS_Q_DEF + MQC.MQOO_FAIL_IF_QUIESCING);
  _gmo = new MQGetMessageOptions();
  _gmo.Options |= MQC.MQGMO_WAIT;
  _gmo.Options |= MQC.MQGMO_SYNCPOINT;
  _gmo.WaitInterval = 1000;  // 1 seconds wait

  // in a loop
  using (TransactionScope t = new TransactionScope())
  {

  var message = new MQMessage();
  try
  {
     _queue.Get(message, _gmo);
  }
  catch (MQException mqe)
  { 
     message = null;
     if (mqe.ReasonCode == 2033)
     {
          Console.WriteLine("No message available");
     }
     else
     {
          throw;
      }
   }
   t.Complete();
 }

//Afterwards:

  if (_queue != null)
   {
  _queue.Close();
  _queue = null;
  }
  if (_queueManager != null)
  {
  _queueManager.Disconnect();
  _queueManager.Close();
  _queueManager = null;
  }

问题是在关闭应用程序后,所有消息重新出现在队列中,而提交SQL数据库中的工作.
如果transactionscope内部发生异常,则SQL事务将回滚,而MQ中的消息似乎保持删除状态(直到我重新启动应用程序).
另外,我看不到.NET客户端和MQ服务器之间的任何DTC活动(这是预期的吗?)

我在这里有点迷失,不胜感激.

>我应该使用哪个MQ客户端?托管,非托管,XA?
>我应该查看DTC活动吗?我如何让托管客户参与?
>应该在transactionscope中创建哪些对象?
>为什么即使我提交了transactionscope,当应用程序结束时消息也会重新出现在队列中?

更新

>我已经在客户端和服务器上同时使用7.1,但是要在生产环境中部署该(服务器)版本将花费很长时间.
>因此,我需要在服务器端使用7.0.x版本,客户端可以使用我需要的任何版本.
>使用7.1客户端连接到MQ6服务器失败,错误代码2354

解决方法:

好吧,您至少需要安装WebSphere MQ v7.1(客户端管理器和队列管理器),才能使用TransactionScope在完全托管的模式下运行全局事务.在这种情况下,MS DTC将担任交易协调员.您发布的有关InfoCenter链接实际上指向WebSphere MQ v7.1.

更新:
在MQ v7.1之前,仅在以MTS作为事务协调器的非托管模式下支持XA事务.非托管模式下的分布式事务的示例代码为here.您将需要安装其他组件,扩展事务客户端(XTC).根据最新公告,XTC是免费提供的.可在您的MQ Server安装映像中找到该可安装文件.

当MQ连接断开连接(基本上调用MQDISC)时,事务中所有未提交的消息都将回滚.因此,消息重新出现在队列中.

标签:ibm-mq,windows,c,net
来源: https://codeday.me/bug/20191031/1977993.html