我有一个 .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 数据库中的工作。 如果事务范围内发生异常,则 SQL 事务回滚,同时 MQ 中的消息似乎保持删除状态(直到我重新启动应用程序)。 此外,我没有看到 .NET 客户端和 MQ 服务器之间有任何 DTC 事件(这是预期的吗?)
我有点迷路了,非常感谢任何帮助。
- 我应该使用哪个 MQ 客户端?托管、非托管、XA?
- 我应该查看 DTC 事件吗?我如何让托管客户参与?
- 应该在事务范围内创建哪些对象?
- 为什么当应用程序结束时消息会重新出现在队列中,即使我提交了事务范围?
更新
- 我已经在客户端和服务器上使用 7.1,但是要在我们的生产环境中部署该(服务器)版本需要很长时间。
- 所以我需要在服务器端使用 7.0.x 版,在客户端我可以使用任何我需要的。
- 使用 7.1 客户端连接到 MQ6 服务器失败,错误代码为 2354
最佳答案
好吧,您至少需要安装 WebSphere MQ v7.1(包括客户端和队列管理器)才能使用 TransactionScope 在完全托管模式下运行全局事务。在这种情况下,MS DTC 将成为事务协调器。您发布的信息中心链接实际上指向 WebSphere MQ v7.1。
更新:
在 MQ v7.1 之前,XA 事务仅在以 MTS 作为事务协调器的非托管模式下受支持。非托管模式下分布式事务的示例代码是here .您将需要安装一个附加组件,即扩展事务客户端 (XTC)。根据最新公告,XTC 是免费提供的。可以在您的 MQ 服务器安装镜像中找到可安装的。
当 MQ 连接断开时(基本上是调用 MQDISC),事务中任何未提交的消息都将回滚。因此消息重新出现在队列中。
关于c# - 如何使用 .net TransactionScope 从 MQ 执行事务性 GET?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13053737/