【发布时间】:2014-01-28 14:47:10
【问题描述】:
下面的示例程序应该定期启动,并且应该尽快处理队列(在另一台机器上)上的所有消息,然后停止。每条消息都应在单独的分布式事务中处理,因为处理过程还需要访问和更改多个数据库。
托管模式似乎太慢了,因为它每 3 秒处理 1 条消息。
非托管模式的性能可以接受,但我有两个问题。
1) 程序结束时,服务器的事件日志包含数百条错误消息,都报相同的错误:
28/01/2014 15:20:49 - Process(8604.48) User(<<username>>) Program(amqrmppa.exe) Host(<<server machinename>>) Installation(Server) VRMF(7.5.0.2) QMgr(<<queuemanager name>>)
Error on receive from host <<client machinename>> (<<client ip>>).
An error occurred receiving data from <<client machinename>> (<<client ip>>) over TCP/IP. This may be due to a communications failure.
The return code from the TCP/IP recv() call was 10054 (X'2746'). Record these values and tell the systems administrator.
2) 对消息数量有限的队列运行程序可以正常运行(除了上面的问题),但是在处理了数百条消息(500+)后,它突然崩溃并出现以下异常:
MQException: MQRC_UOW_ENLISTMENT_ERROR, CompCode 2, Reason: 2354
第二个问题可能与第一个有关,但我看不出代码有什么问题。所有 MQ 对象都已正确断开、关闭和处置。
欢迎所有帮助...
using System;
using System.Collections;
using System.Text;
using System.Transactions;
using IBM.WMQ;
namespace WMQTest
{
internal class Program
{
private const string HostName = "TST010";
private const int Port = 5021;
private const string ChannelName = "CL_QMSTST010";
private const string QueueManagerName = "QMSTST010";
private const string QueueName = "SD.TRANSX.ARCHIVE";
private static readonly MQGetMessageOptions GetMessageOptions = new MQGetMessageOptions
{
Options = MQC.MQGMO_WAIT + MQC.MQGMO_SYNCPOINT,
WaitInterval = 20000
};
private static readonly TransactionOptions TransactionOptions = new TransactionOptions { Timeout = TransactionManager.DefaultTimeout, IsolationLevel = IsolationLevel.Serializable };
private static void Main()
{
try
{
Console.WriteLine("Use managed mode?");
var key = Console.ReadKey(true);
bool managedMode = key.KeyChar == 'y' || key.KeyChar == 'Y';
var properties = new Hashtable
{
{MQC.HOST_NAME_PROPERTY, HostName},
{MQC.PORT_PROPERTY, Port},
{MQC.CHANNEL_PROPERTY, ChannelName},
{
MQC.TRANSPORT_PROPERTY,
managedMode ? MQC.TRANSPORT_MQSERIES_MANAGED : MQC.TRANSPORT_MQSERIES_XACLIENT
}
};
while (true)
{
//starting a transaction scope
using (var transaction = managedMode
? new TransactionScope()
: new TransactionScope(TransactionScopeOption.Required,
TransactionOptions,
EnterpriseServicesInteropOption.Full))
{
using (var queueManager = new MQQueueManager(QueueManagerName, properties))
{
using (
MQQueue queue = queueManager.AccessQueue(QueueName,
MQC.MQOO_INPUT_AS_Q_DEF +
MQC.MQOO_FAIL_IF_QUIESCING))
{
var message = new MQMessage();
try
{
queue.Get(message, GetMessageOptions);
}
catch (MQException ex)
{
if (ex.CompCode != 2 || ex.ReasonCode != MQC.MQRC_NO_MSG_AVAILABLE)
{
throw;
}
//No message available, stop
break;
}
//TODO: DO SOME INTERESTING DATABASE STUFF HERE
Console.WriteLine(Encoding.ASCII.GetString(message.MessageId));
//
message.ClearMessage();
queue.Close();
}
queueManager.Disconnect();
}
transaction.Complete();
}
}
}
catch (Exception ex)
{
Console.WriteLine("EXCEPTION OCCURRED");
Console.WriteLine("==================");
Console.WriteLine(ex);
}
}
}
}
【问题讨论】:
标签: c# .net ibm-mq distributed-transactions