【问题标题】:How to do a transactional GET from MQ using the .net TransactionScope?如何使用 .net TransactionScope 从 MQ 执行事务性 GET?
【发布时间】:2012-10-14 18:14:27
【问题描述】:

我有一个需要包含 MSSQL 数据库和 IBM MQ 队列的 .NET TransactionScope。

我在完全托管模式下使用 .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

隐式事务 以下代码描述了 WebSphere MQ .NET 应用程序如何使用 .NET 隐式事务放置消息 编程。

使用 (TransactionScope scope = new TransactionScope ()) { Q.Put (putMsg,pmo);范围。完成(); }

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 数据库中的工作已提交。 如果在事务范围内发生异常,SQL 事务将回滚,而 MQ 中的消息似乎保持被删除(直到我重新启动应用程序)。 此外,我没有看到 .NET 客户端和 MQ 服务器之间的任何 DTC 活动(这是预期的吗?)

我有点迷路了,非常感谢任何帮助。

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

更新

  • 我已经在客户端和服务器上使用了 7.1,但是在我们的生产环境中部署该(服务器)版本需要很长时间。
  • 所以我需要在服务器端使用 7.0.x 版本,在客户端我可以使用任何我需要的东西。
  • 使用 7.1 客户端连接到 MQ6 服务器失败,错误代码为 2354

【问题讨论】:

标签: c# .net windows ibm-mq


【解决方案1】:

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

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

当一个 MQ 连接断开时(基本上是调用 MQDISC),事务中任何未提交的消息都会被回滚。因为这个消息重新出现在队列中。

【讨论】:

  • 那么如果我使用 Unamanged XA 客户端,我应该能够在同一个事务范围内同时获取 SQL 和 MQ 吗? (不升级MQ)
  • 如何确定我的 WebSphere MQ v7.1 是否也已经安装了 XTC?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-04
  • 1970-01-01
  • 2020-04-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多