Author |
Message
|
freak |
Posted: Wed Mar 17, 2010 8:07 pm Post subject: controlled put and get before commit/backout in .Net |
|
|
Novice
Joined: 28 Feb 2010 Posts: 18
|
Hi all,
i am trying to create a library with put, get, commit and backout methods for other system to use. its basic requirement is to allow the system to be able to multiple put/get of messages before he decides to commit or backout.
I have got a global MQQueueManager variable which will be used for both putMessage and getMessage method, since they are in one transaction [i assume]. But this doesnt work out. Shld i be using one MQQueueManager for each put and get and not combine them as one?
Had viewed thru this forum and i dun seemed to be able to find any related info.
Can some kind souls out there guide me to get this done? thanks.
the Put method:
public void PutMessage(string correlationID, string QMName, string QName, string message)
{
MQQueue requestQueue;
MQRCText mqrcText = new MQRCText();
MQMessage requestMessage;
// Create Queue Manager Object. This will also CONNECT the Queue Manager
try
{
if (mqQMgr == null || !mqQMgr.IsConnected)
{
mqQMgr = new MQQueueManager(QMName);
}
}
catch (MQException mqe)
{
string strError = mqrcText.getMQRCText(mqe.Reason);
this.Backout();
throw new Exception("Error trying to create Queue Manager Object. Error: " + mqe.Message + ", Details: " + strError);
}
// Open Request Queue for writing our request
try
{
requestQueue = mqQMgr.AccessQueue(QName,
MQC.MQOO_OUTPUT // open queue for output
+ MQC.MQOO_FAIL_IF_QUIESCING); // but not if MQM stopping
}
catch (MQException mqe)
{
string strError = mqrcText.getMQRCText(mqe.Reason);
this.Backout();
throw new Exception("Error trying to open Queue for writing. Error: " + mqe.Message + ", Details: " + strError);
}
try
{
MQPutMessageOptions mqPutMsgOpts = new MQPutMessageOptions();
mqPutMsgOpts.Options = MQC.MQPMO_SYNCPOINT;
requestMessage = new MQMessage();
requestMessage.CorrelationId = StrToByteArray(correlationID);
requestMessage.WriteBytes(message);
requestQueue.Put(requestMessage, mqPutMsgOpts);
if (requestQueue.OpenStatus) requestQueue.Close();
return;
}
catch (MQException mqe)
{
string strError = mqrcText.getMQRCText(mqe.Reason);
if (requestQueue.OpenStatus) requestQueue.Close();
this.Backout();
throw new Exception("Error trying to PUT Message to Queue. Error: " + mqe.Message + ", Details: " + strError);
}
}
the GET method
public Dictionary<string, string> GetMessage(string QMName, string QName)
{
MQQueue requestQueue;
MQRCText mqrcText = new MQRCText();
// Create Queue Manager Object. This will also CONNECT the Queue Manager
try
{
if (mqQMgr == null || !mqQMgr.IsConnected)
{
mqQMgr = new MQQueueManager(QMName);
}
}
catch (MQException mqe)
{
string strError = mqrcText.getMQRCText(mqe.Reason);
this.Backout();
throw new Exception("Error trying to create Queue Manager Object. Error: " + mqe.Message + ", Details: " + strError);
}
// Open Request Queue for reading/ getting the request
try
{
requestQueue = mqQMgr.AccessQueue(QName,
MQC.MQOO_INPUT_AS_Q_DEF // open queue for input
+ MQC.MQOO_FAIL_IF_QUIESCING); // but not if MQM stopping
}
catch (MQException mqe)
{
string strError = mqrcText.getMQRCText(mqe.Reason);
this.Backout();
throw new Exception("Error trying to open Queue for reading. Error: " + mqe.Message + ", Details: " + strError);
}
try
{
MQMessage requestMessage = new MQMessage();
MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.Options = MQC.MQGMO_WAIT + MQC.MQGMO_FAIL_IF_QUIESCING + MQC.MQGMO_SYNCPOINT;
gmo.WaitInterval = 5000; // wait for an interval
gmo.MatchOptions = MQC.MQMO_MATCH_CORREL_ID; //MQC.MQMO_NONE; // no matching required
requestQueue.Get(requestMessage, gmo);
Dictionary<string, string> myGetQueueMsg = new Dictionary<string, string>();
myGetQueueMsg.Add("CORRELATIONID", ASCIIEncoding.ASCII.GetString(requestMessage.CorrelationId));
myGetQueueMsg.Add("MESSAGE", requestMessage.ReadString(requestMessage.MessageLength));
if (requestQueue.OpenStatus) requestQueue.Close();
return myGetQueueMsg;
}
catch (MQException mqe)
{
if (mqe.Reason == 2033) return null; // MQRC_NO_MSG_AVAILABLE
string strError = mqrcText.getMQRCText(mqe.Reason);
if (requestQueue.OpenStatus) requestQueue.Close();
this.Backout();
throw new Exception("Error trying to GET message from Queue. Error: " + mqe.Message + ", Details: " + strError);
}
} // End of ReadMsg
the COMMIT method
public void Commit()
{
this.clsMQMsg.Commit();
}
the BACKOUT method
public void Backout()
{
this.clsMQMsg.Backout();
} |
|
Back to top |
|
 |
fjb_saper |
Posted: Thu Mar 18, 2010 10:38 am Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
You need to read up a lot hard and check if what you attempt is worth the effort.
You need most probably to keep the connections separate by thread and keep state by connection.
Have fun  _________________ MQ & Broker admin |
|
Back to top |
|
 |
mvic |
Posted: Thu Mar 18, 2010 2:43 pm Post subject: Re: controlled put and get before commit/backout in .Net |
|
|
 Jedi
Joined: 09 Mar 2004 Posts: 2080
|
freak wrote: |
i am trying to create a library with put, get, commit and backout methods for other system to use. its basic requirement is to allow the system to be able to multiple put/get of messages before he decides to commit or backout. |
I know I might regret asking, but: why develop a wrapper over the APIs MQ gives you? The APIs are already usable and fully-featured. What are you wanting to add to what's already there? |
|
Back to top |
|
 |
freak |
Posted: Thu Mar 18, 2010 6:01 pm Post subject: |
|
|
Novice
Joined: 28 Feb 2010 Posts: 18
|
fjb_saper wrote: |
You need to read up a lot hard and check if what you attempt is worth the effort.
You need most probably to keep the connections separate by thread and keep state by connection.
Have fun  |
You are right. Had tried out on the read and browse next feature and it only works in a single thread.
Are you able to point out where i could read up more on these? What i managed to find is sg247012.pdf [Websphere MQ Solutions in a Microsoft .Net]. In it is just a brief mention of transactions.
Had done some googling but they didnt have much info as well. |
|
Back to top |
|
 |
freak |
Posted: Thu Mar 18, 2010 6:03 pm Post subject: Re: controlled put and get before commit/backout in .Net |
|
|
Novice
Joined: 28 Feb 2010 Posts: 18
|
[quote="mvic"][quote="freak"]i am trying to create a library with put, get, commit and backout methods for other system to use. its basic requirement is to allow the system to be able to multiple put/get of messages before he decides to commit or backout.[/quote]
I know I might regret asking, but: why develop a wrapper over the APIs MQ gives you? The APIs are already usable and fully-featured. What are you wanting to add to what's already there?[/quote]
Needed that because it is some legacy system which my team is not managing. |
|
Back to top |
|
 |
freak |
Posted: Thu Mar 18, 2010 6:29 pm Post subject: |
|
|
Novice
Joined: 28 Feb 2010 Posts: 18
|
[quote="fjb_saper"]
You need most probably to keep the connections separate by thread and keep state by connection.
[/quote]
If i were to maintain the connections using separate thread, will i be able to do something like this, with assumption that the queue is empty at the start:
put msg - put msg - put msg - browse first msg - browse next msg - get msg where current cursor is [2nd msg] - commit
will i be able to get two msg in the queue at the end of the transaction? will i be able to retrieve information of the second message successfully without a commit? |
|
Back to top |
|
 |
Vitor |
Posted: Thu Mar 18, 2010 7:39 pm Post subject: |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
freak wrote: |
Are you able to point out where i could read up more on these? |
The InfoCentre at the top of this page is a good start  _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
Vitor |
Posted: Thu Mar 18, 2010 7:42 pm Post subject: Re: controlled put and get before commit/backout in .Net |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
freak wrote: |
Needed that because it is some legacy system which my team is not managing. |
That's no answer. It doesn't matter if this legacy system includes your developed code or the provided APIs, they still need to change their code outside your management.
And if you wrap the APIs in more code, this will make finding problems harder for no benefit I can see.
So what am I missing?  _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
Vitor |
Posted: Thu Mar 18, 2010 7:45 pm Post subject: |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
freak wrote: |
If i were to maintain the connections using separate thread, will i be able to do something like this, with assumption that the queue is empty at the start:
put msg - put msg - put msg - browse first msg - browse next msg - get msg where current cursor is [2nd msg] - commit |
No.
freak wrote: |
will i be able to get two msg in the queue at the end of the transaction? |
No.
freak wrote: |
will i be able to retrieve information of the second message successfully without a commit? |
No.
You seriously need to research this, and possibly push back on the requirement. It's very anti-pattern to need to read a message back inside a unit of work.
It's also a bad idea to browse messages, especially with a cursor. Browse operations are not good, and cursors are hideously inefficent. _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
Vitor |
Posted: Thu Mar 18, 2010 7:46 pm Post subject: |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
Moved to more relevant section _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
|