Put message

You can perform assured message delivery using synchronous message transmission, but the application must take responsibility for error handling.

The confirmID parameter of the putMessage method dictates whether a confirm flow is expected or not. A value of zero means that message transmission occurs in one flow, while a value of greater than zero means that a confirm flow is expected. The target queue manager logs the message to the destination queue as usual, but the message is locked and invisible to WebSphere MQ Everyplace applications, until a confirm flow is received. When you put messages with the confirmID, the messages are ordered by confirm time, not arrival time.

An WebSphere MQ Everyplace application can issue a put message confirmation using the confirmPutMessage method. Once the target queue manager receives the flow generated by this command, it unlocks the message, and makes it visible to WebSphere MQ Everyplace applications. You can confirm only one message at a time. It is not possible to confirm a batch of messages.

Figure 5. Assured put of synchronous messages

Diagrammatic representation of description above.

The confirmPutMessage() method requires you to specify the UniqueID of the message, not the confirmID used in the prior put message command. The confirmID is used to restore messages that remain locked after a transmission failure. This is explained in detail on page ***.

A skeleton version of the code required for an assured put is shown below:

Java codebase
	long confirmId = MQe.uniqueValue();
	
	try
	{
 	 qmgr.putMessage( "RemoteQMgr", "RemoteQueue", 
								msg, null, confirmId );
	}
	catch( Exception e )
	{
	  /* handle any exceptions*/
	}
	
	try
	{
  		qmgr.confirmPutMessage( "RemoteQMgr", "RemoteQueue", 
                          msg.getMsgUIDFields() );
	}
	catch ( Exception e )
	{
 	 /* handle any exceptions			*/
	}	
 

C codebase
	/* generate confirm Id */
	MQEINT64 confirmId;
	rc = mqe_uniqueValue(&exceptBlock,
								&confirmId);
	
	/* put message to queue using this confirm Id */
	if(MQERETURN_OK == rc) {
    	rc = mqeQueueManager_putMessage(hQMgr, 
											&exceptBlock, 
											hQMgrName, hQName, 
											hMsg, NULL, confirmId);
    	/* now confirm the message put */
    	if(MQERETURN_OK == rc) {
        		/* first get the message uid fields */
        		MQeFieldsHndl hFilter;
        		rc = mqeFieldsHelper_getMsgUidFields(hMsg, 
														&exceptBlock,
														&hFilter);
        		if(MQERETURN_OK == rc) {
            	rc = mqeQueueManager_confirmPutMessage(hQMgr, 
														&exceptBlock,
														hQMgrName, 
														hQName, hFilter);
        		}
    	}
	}
 

If a failure occurs during step 1 in Figure 5 the application should retransmit the message. There is no danger of introducing duplicate messages into the WebSphere MQ Everyplace network since the message at the target queue manager is not made visible to applications until the confirm flow has been successfully processed.

If the WebSphere MQ Everyplace application retransmits the message, it should also inform the target queue manager that this is happening. The target queue manager deletes any duplicate copy of the message that it already has. The application sets the MQe.Msg_Resend field to do this.

If a failure occurs during step 2 in Figure 5 the application should send the confirm flow again. There is no danger in doing this since the target queue manager ignores any confirm flows it receives for messages that it has already confirmed. This is shown in the following example, taken from examples.application.example6.

Java codebase
	boolean msgPut     = false;	
		/* put successful?		*/
	boolean msgConfirm = false;	
		/* confirm successful?		*/
	int maxRetry       = 5;	
		/* maximum number of retries		*/
	
	long confirmId = MQe.uniqueValue();
	
	int retry = 0;
	while( !msgPut && 
					retry < maxRetry )
	{
  	try
  	{
    	qmgr.putMessage( "RemoteQMgr", 
								"RemoteQueue", 
								msg, null, 
								confirmId );
   	msgPut = true; 		
	/* message put successful             */
  	}
  	catch( Exception e )
  	{
    	/* handle any exceptions	*/
    	/* set resend flag for 
			retransmission of message	*/
    	msg.putBoolean( MQe.Msg_Resend, true );
    	retry ++;
  	}
	}
	
	if ( !msgPut ) 		
		/* was put message successful?*/
    	/* Number of retries has 
			exceeded the maximum allowed, 
	 	/*so abort the put*/
   	/* message attempt */
  return;
	
	retry = 0;
	while( !msgConfirm && 
						retry < maxRetry )
	{
  	try
  	{
    	qmgr.confirmPutMessage( "RenoteQMgr", 
									"RemoteQueue", 
                          msg.getMsgUIDFields());
    	msgConfirm = true;  	
	/* message confirm successful*/
  	}
  	catch ( Exception e )
  	{
    	/* handle any exceptions*/
    	/* An Except_NotFound 
			exception means */ 
		/*that the message has already  	*/
    	/* been confirmed */
    	if ( e instanceof MQeException && 
         ((MQeException)e).code() == Except_NotFound )   
      	putConfirmed = true;            
			/* confirm successful */
    	/* another type of exception - 
			need to reconfirm message */
    	retry ++;
  	}
	}
 

C codebase
MQEINT32 maxRetry = 5;
 
rc = mqeQueueManager_putMessage(hQMgr, 
										&exceptBlock, 
										hQMgrName, 
										hQName, hMsg, 
										NULL, confirmId);
 
/* if the put attempt fails, 
		retry up to the maximum number*/
/*of retry times permitted, 
		setting the re-send flag. */
while (MQERETURN_OK != rc 
					&& --maxRetry > 0 ) {
    rc = mqeFields_putBoolean(hMsg, &exceptBlock, 
											MQE_MSG_RESEND, MQE_TRUE);
    if(MQERETURN_OK == rc) {
       rc = mqeQueueManager_putMessage(hQMgr, &exceptBlock, 
														hQMgrName, hQName, 
														hMsg, NULL, confirmId);
    }
}
 
if(MQERETURN_OK == rc) {
    MQeFieldsHndl hFilter;
    maxRetry = 5;
    rc = mqeFieldsHelper_getMsgUidFields(hMsg, 
												&exceptBlock, 
												&hFilter);
    if(MQERETURN_OK == rc) {
          rc = mqeQueueManager_confirmPutMessage(hQMgr, 
													&exceptBlock, 
													hQMgrName, hQName, 
													hFilter);
    }
     while (MQERETURN_OK != rc 
								&& --maxRetry > 0 ) {
             rc = mqeQueueManager_confirmPutMessage(hQMgr, 
																		&exceptBlock, 
																			hQMgrName, 
																			hQName, 
																			hFilter);
    }
}
 


© IBM Corporation 2002. All Rights Reserved