IBM MQ 交易和 .net
IBM MQ transactions and .net
我使用 .net C#(IBM MQ 版本 9.1.5)从队列中提取消息。所以我没有问题连接到队列和获取消息。
我看过有交易的概念Distributed Transactions.
我尝试了以下方法:
var getMessageOptions = new MQGetMessageOptions();
getMessageOptions = new MQGetMessageOptions();
getMessageOptions.Options += MQC.MQGMO_WAIT + MQC.MQGMO_SYNCPOINT;
getMessageOptions.WaitInterval = 20000; // 20 seconds wait
Transaction oldAmbient = Transaction.Current;
using (var tx = new CommittableTransaction())
{
try
{
int i = queue.CurrentDepth;
Log.Information($"Current queue depth is {i} message(s)");
var message = new MQMessage();
queue.Get(message, getMessageOptions);
string messageStr = message.ReadString(message.DataLength);
Log.Information(messageStr);
tx.Commit();
}
catch (MQException e) when (e.Reason == 2033)
{
// Report exceptions other than "no messages in the queue"
Log.Information("No messages in the queue");
tx.Rollback();
}
catch (Exception ex)
{
Log.Error($"Exception when trying to capture a message from the queue: {ex.Message}");
tx.Rollback();
}
我收到错误代码 2035。
查看 Recovering Transactions 上的文档,"SYSTEM.DOTNET.XARECOVERY.QUEUE" 住在哪里,是在 queuemanger 上吗?
我需要为此启用权限吗?
我还看到提到了 Microsoft 分布式事务管理器,这是我们需要在本地主机上 运行 才能使分布式事务工作的东西吗?
如果正在使用 MQ 分布式事务功能,那么用户 运行 应用程序应该有权 "SYSTEM.DOTNET.XARECOVERY.QUEUE"。如果事务不完整 "SYSTEM.DOTNET.XARECOVERY.QUEUE" 队列保存不完整的信息交易作为该队列中的消息,稍后可用于解决交易。
根据您在评论中提出的方案,即“我们只想将消息保存到文件中。我的想法是,如果这有问题,我可以回滚事务." 。如果 MQ 是唯一的资源管理器,那么您不必使用分布式事务。在同步点下获取消息也可以用来代替分布式事务。如果使用多个资源管理器,分布式事务将很有用。
要在同步点下获取消息,可以通过更新主机名、通道、端口、队列和队列管理器名称来使用以下示例代码:
var getMessageOptions = new MQGetMessageOptions();
getMessageOptions = new MQGetMessageOptions();
getMessageOptions.Options += MQC.MQGMO_WAIT + MQC.MQGMO_SYNCPOINT;
getMessageOptions.WaitInterval = 20000; // 20 seconds wait
Hashtable props = new Hashtable();
props.Add(MQC.HOST_NAME_PROPERTY, "localhost");
props.Add(MQC.CHANNEL_PROPERTY, "DOTNET.SVRCONN");
props.Add(MQC.PORT_PROPERTY, 3636);
MQQueueManager qm = new MQQueueManager("QM", props);
MQQueue queue = qm.AccessQueue("Q1", MQC.MQOO_INPUT_AS_Q_DEF);
try
{
var message = new MQMessage();
queue.Get(message, getMessageOptions);
//to commit the message
qm.Commit();
string messageStr = message.ReadString(message.DataLength);
}
catch (MQException e) when (e.Reason == 2033)
{
// Report exceptions other than "no messages in the queue"
Log.Information("No messages in the queue");
}
catch (Exception ex)
{
Log.Error($"Exception when trying to capture a message from the queue:
}
我使用 .net C#(IBM MQ 版本 9.1.5)从队列中提取消息。所以我没有问题连接到队列和获取消息。 我看过有交易的概念Distributed Transactions.
我尝试了以下方法:
var getMessageOptions = new MQGetMessageOptions();
getMessageOptions = new MQGetMessageOptions();
getMessageOptions.Options += MQC.MQGMO_WAIT + MQC.MQGMO_SYNCPOINT;
getMessageOptions.WaitInterval = 20000; // 20 seconds wait
Transaction oldAmbient = Transaction.Current;
using (var tx = new CommittableTransaction())
{
try
{
int i = queue.CurrentDepth;
Log.Information($"Current queue depth is {i} message(s)");
var message = new MQMessage();
queue.Get(message, getMessageOptions);
string messageStr = message.ReadString(message.DataLength);
Log.Information(messageStr);
tx.Commit();
}
catch (MQException e) when (e.Reason == 2033)
{
// Report exceptions other than "no messages in the queue"
Log.Information("No messages in the queue");
tx.Rollback();
}
catch (Exception ex)
{
Log.Error($"Exception when trying to capture a message from the queue: {ex.Message}");
tx.Rollback();
}
我收到错误代码 2035。
查看 Recovering Transactions 上的文档,"SYSTEM.DOTNET.XARECOVERY.QUEUE" 住在哪里,是在 queuemanger 上吗? 我需要为此启用权限吗?
我还看到提到了 Microsoft 分布式事务管理器,这是我们需要在本地主机上 运行 才能使分布式事务工作的东西吗?
如果正在使用 MQ 分布式事务功能,那么用户 运行 应用程序应该有权 "SYSTEM.DOTNET.XARECOVERY.QUEUE"。如果事务不完整 "SYSTEM.DOTNET.XARECOVERY.QUEUE" 队列保存不完整的信息交易作为该队列中的消息,稍后可用于解决交易。
根据您在评论中提出的方案,即“我们只想将消息保存到文件中。我的想法是,如果这有问题,我可以回滚事务." 。如果 MQ 是唯一的资源管理器,那么您不必使用分布式事务。在同步点下获取消息也可以用来代替分布式事务。如果使用多个资源管理器,分布式事务将很有用。
要在同步点下获取消息,可以通过更新主机名、通道、端口、队列和队列管理器名称来使用以下示例代码:
var getMessageOptions = new MQGetMessageOptions();
getMessageOptions = new MQGetMessageOptions();
getMessageOptions.Options += MQC.MQGMO_WAIT + MQC.MQGMO_SYNCPOINT;
getMessageOptions.WaitInterval = 20000; // 20 seconds wait
Hashtable props = new Hashtable();
props.Add(MQC.HOST_NAME_PROPERTY, "localhost");
props.Add(MQC.CHANNEL_PROPERTY, "DOTNET.SVRCONN");
props.Add(MQC.PORT_PROPERTY, 3636);
MQQueueManager qm = new MQQueueManager("QM", props);
MQQueue queue = qm.AccessQueue("Q1", MQC.MQOO_INPUT_AS_Q_DEF);
try
{
var message = new MQMessage();
queue.Get(message, getMessageOptions);
//to commit the message
qm.Commit();
string messageStr = message.ReadString(message.DataLength);
}
catch (MQException e) when (e.Reason == 2033)
{
// Report exceptions other than "no messages in the queue"
Log.Information("No messages in the queue");
}
catch (Exception ex)
{
Log.Error($"Exception when trying to capture a message from the queue:
}