|
RSS Feed - WebSphere MQ Support
|
RSS Feed - Message Broker Support
|
 |
|
XA problems using WebSphere MQ 6.0.1.1 and .NET 2.0 |
« View previous topic :: View next topic » |
Author |
Message
|
torkil |
Posted: Thu Jun 22, 2006 12:40 am Post subject: XA problems using WebSphere MQ 6.0.1.1 and .NET 2.0 |
|
|
Newbie
Joined: 21 Jun 2006 Posts: 2 Location: Denmark
|
Hi. This would be my first posting in this forum. I am experiencing the following problem:
I am trying to get MQ to enlist in a XA transaction. The transaction manager is to be MSDTC.
I have the following sample code ... a .NET 2.0 Console application
Program.cs
ComPlusTransactionContext.cs
MQClassSWC.cs
See details at the bottom of this posting.
What am I doing wrong.
I have added the following entry in the registry hive
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSDTC\XADLL
amqmtsxatmc.dll
C:\Program Files\IBM\WebSphere MQ\bin\amqmtsxatmc.dll
I can verify in the Filmon utility from sysinternals that the registryhive is read succesfully.
I have the following environment variables present
- NMQ_MQ_LIB=C:\Program Files\IBM\WebSphere MQ\bin\mqic32xa.dll
- MQNOREMPOOL=1
Furthermore the NETWORKSERVICE has full access the the WebSphere MQ installation folder.
The transaction is showing up in the DTC transaction list, but I get the following warning in the event log:
Source := MSDTC; Event := 53284
--------------------------------------------------
The XA Transaction Manager attempted to load the XA resource manager DLL. The call to LOADLIBRARY for the XA resource manager DLL failed: DLL=C:\Program Files\IBM\WebSphere MQ\bin\amqmtsxatmc.dll File=d:\qxp_slp\com\com1x\dtc\dtc\xatm\src\xarmconn.cpp Line=2467.
For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.
--------------------------------------------------
Further more my Console has the following output:
Enter timeout in milliseconds
1500
Entering COM+ context
Calling get
MQ Backout
CompCode: 2, Reason: 2354
D:\Projects\ConsoleServicedComponent\bin\Debug>
--------------------------------------------------
Please help me!
Program.cs
--------------------------------------------------
using System;
using IBM.WMQ;
using MQSWC;
class Program
{
public static void Main(string[] args)
{
Console.Clear();
Console.Title = "Console Serviced Component";
Console.WriteLine();
int milliseconds;
while(true)
{
Console.WriteLine("Enter timeout in milliseconds");
string ms = Console.ReadLine();
try
{
milliseconds = Convert.ToInt32(ms);
break;
}
catch (FormatException) { }
}
try
{
Console.WriteLine("Entering COM+ context");
using (ComPlusTransactionContext comPlus = new ComPlusTransactionContext())
{
using (MQClassSWC mq = new MQClassSWC())
{
mq.WaitInterval = milliseconds;
try
{
Console.WriteLine("Calling get");
MQMessage message = mq.Get();
Console.WriteLine("Calling put");
mq.Put(message);
mq.Commit();
Console.WriteLine("MQ Committed");
}
catch(MQException mqEx)
{
if (mqEx.CompletionCode.Equals(MQC.MQCC_FAILED) && mqEx.Reason.Equals(MQC.MQRC_NO_MSG_AVAILABLE))
{
mq.Commit();
}
else
{
//Console.WriteLine(mqEx);
Console.WriteLine("MQ Backout");
mq.Backout();
throw;
}
}
mq.Close();
}
comPlus.Complete();
Console.WriteLine("Exiting COM+ context");
}
}
catch(Exception ex)
{
Console.WriteLine(ex);
}
}
}
--------------------------------------------------
ComPlusTransactionContext.cs
--------------------------------------------------
using System;
using System.EnterpriseServices;
internal class ComPlusTransactionContext : IDisposable
{
private bool _voteToCommit;
// Enter can throw, so we need to know if we need to call Leave in Dispose
private bool _enterSucceeded;
internal ComPlusTransactionContext()
{
ServiceDomain.Enter(GetConfig());
_enterSucceeded = true;
}
private ServiceConfig GetConfig()
{
ServiceConfig svcConfig = new ServiceConfig();
//Enable tracking so you can see the action in the COM+ component viewer
svcConfig.TrackingEnabled = true;
svcConfig.TrackingAppName = "MQ Listener slave";
// get my own stack frame
System.Diagnostics.StackFrame sf0 = new System.Diagnostics.StackFrame(0, true);
// for the TrackingComponentName, walk the callstack backwards
// until we get a type outside the current one.
System.Diagnostics.StackFrame sfn = null;
for (int i = 1; i < 6; i++)
{
sfn = new System.Diagnostics.StackFrame(i, true);
if (sf0.GetMethod().DeclaringType.FullName == sfn.GetMethod().DeclaringType.FullName) break;
}
svcConfig.TrackingComponentName = sfn.GetMethod().DeclaringType.FullName;
svcConfig.Transaction = TransactionOption.Required;
return svcConfig;
}
public void Dispose()
{
if (_enterSucceeded)
{
if (!_voteToCommit)
{
ContextUtil.SetAbort();
}
ServiceDomain.Leave();
}
}
public void Complete() { _voteToCommit = true; }
}
--------------------------------------------------
MQClassSWC.cs
--------------------------------------------------
using System;
using System.Collections;
using IBM.WMQ;
[assembly: CLSCompliant(true)]
namespace MQSWC
{
public class MQClassSWC : IDisposable
{
private MQQueueManager _queueManager;
private MQQueue _requestQueue;
private MQQueue _replyQueue;
private static int _getOpenOptions { get { return MQC.MQOO_INPUT_SHARED | MQC.MQOO_FAIL_IF_QUIESCING; } }
private static int _putOpenOptions { get { return MQC.MQOO_OUTPUT | MQC.MQOO_FAIL_IF_QUIESCING; } }
private MQGetMessageOptions _getMessageOptions;
private MQPutMessageOptions _putMessageOptions;
private bool _connected;
private int _waitIntreval = 10000;
public MQClassSWC()
{
string connectionType;
connectionType = MQC.TRANSPORT_MQSERIES_XACLIENT;
//connectionType = MQC.TRANSPORT_MQSERIES_MANAGED;
//connectionType = MQC.TRANSPORT_MQSERIES_BINDINGS;
//connectionType = MQC.TRANSPORT_MQSERIES_CLIENT;
Hashtable properties = InitializeConnectionProperties(connectionType,
"127.0.0.1", "LIVNET", 1414);
_queueManager = new MQQueueManager("QM_wdkcphtool21l", properties);
_requestQueue = _queueManager.AccessQueue("SafeRequestQueue", _getOpenOptions);
_replyQueue = _queueManager.AccessQueue("RTQ", _putOpenOptions);
WaitInterval = 10000;
_connected = true;
}
public int WaitInterval
{
get {
return _waitIntreval;
}
set{_waitIntreval = value;}
}
[CLSCompliant(false)]
public MQMessage Get()
{
_getMessageOptions = new MQGetMessageOptions();
_getMessageOptions.Options = MQC.MQGMO_WAIT | MQC.MQGMO_SYNCPOINT | MQC.MQGMO_FAIL_IF_QUIESCING;
//_getMessageOptions.Options = MQC.MQGMO_WAIT | MQC.MQGMO_NO_SYNCPOINT | MQC.MQGMO_FAIL_IF_QUIESCING;
_getMessageOptions.WaitInterval = _waitIntreval;
MQMessage message = new MQMessage();
//message.Persistence = MQC.MQPER_PERSISTENT;
_requestQueue.Get(message, _getMessageOptions);
return message;
}
[CLSCompliant(false)]
public void Put(MQMessage message)
{
_putMessageOptions = new MQPutMessageOptions();
_putMessageOptions.Options = MQC.MQPMO_NONE | MQC.MQPMO_SYNCPOINT | MQC.MQPMO_FAIL_IF_QUIESCING;
//_putMessageOptions.Options = MQC.MQPMO_NONE | MQC.MQPMO_NO_SYNCPOINT | MQC.MQPMO_FAIL_IF_QUIESCING;
_replyQueue.Put(message, _putMessageOptions);
}
public void Commit()
{
_queueManager.Commit();
}
public void Backout()
{
_queueManager.Backout();
}
private static Hashtable InitializeConnectionProperties(string connectionType, string hostname, string channel, int port)
{
Hashtable connectionProperties = new Hashtable();
// Add the connection type
connectionProperties.Add(MQC.TRANSPORT_PROPERTY, connectionType);
// Set up the rest of the connection properties, based on the
// connection type requested
switch (connectionType)
{
case MQC.TRANSPORT_MQSERIES_BINDINGS:
break;
case MQC.TRANSPORT_MQSERIES_CLIENT:
case MQC.TRANSPORT_MQSERIES_XACLIENT:
case MQC.TRANSPORT_MQSERIES_MANAGED:
connectionProperties.Add(MQC.HOST_NAME_PROPERTY, hostname);
connectionProperties.Add(MQC.CHANNEL_PROPERTY, channel);
connectionProperties.Add(MQC.PORT_PROPERTY, port);
connectionProperties.Add(MQC.CONNECT_OPTIONS_PROPERTY, MQC.MQCNO_HANDLE_SHARE_NONE);
break;
}
return connectionProperties;
}
public void Close()
{
if (_replyQueue != null)
_replyQueue.Close();
if (_requestQueue != null)
_requestQueue.Close();
if (_queueManager != null)
{
_queueManager.Close();
_queueManager.Disconnect();
}
}
#region IDisposable Members
void IDisposable.Dispose()
{
if (_connected)
Close();
}
#endregion
}
}
--------------------------------------------------
And yes ... I have enabled XA transaction on the MSDTC.
My environment is Windows XP Professional SP2 + every posible hotfix.
My Channel is a server-connection over TCP
My queue is a persistent queue. |
|
Back to top |
|
 |
JasonE |
Posted: Thu Jun 22, 2006 12:05 pm Post subject: |
|
|
Grand Master
Joined: 03 Nov 2003 Posts: 1220 Location: Hursley
|
Hi
Use filemon and regmon + mqtrace
1. Look in the regmon for the xadll registry key read by msdtc, and ensure there are no access denieds around that point. Are there any subsequent MQ registry key reads (probably not, given your description)
2. Then look in the filemon for the load of the dependencies
Chances are one of the those is failing to load with access denied.
3. Look to see if you get an MQ trace from the MSDTC process
Note - .net 2 isnt a supported environment yet and I believe there are a few known problems with it
If the problem persists, PM me (but bear in mind I may be out for a while after this w/e)
Jason |
|
Back to top |
|
 |
torkil |
Posted: Fri Jun 23, 2006 5:38 am Post subject: |
|
|
Newbie
Joined: 21 Jun 2006 Posts: 2 Location: Denmark
|
Hi again.
wow 57 review and 1 reply in 24 hours. So I am not the only one doing XA with MSDTC and MQ.
Just to let you know ... I have found that my code works on Windows 2003 server enterprise edition. Gues eigther my Windows XP Professional installation is corrupted or we have a bug in eigther Windows XP or MQ on Windows XP Proffessional |
|
Back to top |
|
 |
|
|
 |
|
Page 1 of 1 |
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|
|
|