C-C++ Code Example: Sending a Message Using a Single-Message Transaction

 

Applies To: Windows 10, Windows 7, Windows 8, Windows 8.1, Windows Server 2008, Windows Server 2008 R2, Windows Server 2012, Windows Server 2012 R2, Windows Server Technical Preview, Windows Vista

This example provides an application-defined function the sends a message in a single-message transaction to a destination queue provided by the caller.

Message Queuing provides a single-message transaction that implicitly uses the internal transaction support provided by Message Queuing. The benefits of this type of transaction include:

  • Greater speed, compared to using an external transaction coordinator.

  • Simplified application code (MQBeginTransaction does not have to be called).

  • Exactly-once delivery without the need to coordinate other activities within a single transaction.

For more information on single-message transactions, see Single-Message Transactions. For information on other Message Queuing transactions, see Transactions.

To send a message in a single-message transaction

  1. Define the structures needed to send the message.

  2. Specify the properties of the message that will be set by the application.

  3. Initialize the MQMSGPROPS structure.

  4. Call MQOpenQueue to open the transactional queue with send access.

  5. Call MQSendMessage to send the message to the destination queue. Note that the pTransaction parameter of the call is set to MQ_SINGLE_MESSAGE.

  6. Call MQCloseQueue to close the destination queue.

Code Example

The following code example can be run on all versions of Message Queuing.

HRESULT SendSingleTransMessage(  
                               LPCWSTR wszDestFormatName  
                               )  
{  
  
  // Validate the input string.  
  if (wszDestFormatName == NULL)  
  {  
    return MQ_ERROR_INVALID_PARAMETER;  
  }  
  
  // Define the maximum number of properties and a property counter.  
  const int NUMBEROFPROPERTIES = 2;              // Maximum number of properties  
  DWORD cPropId = 0;                             // Property counter  
  
  //Define an MQMSGPROPS structure.  
  MQMSGPROPS msgprops;  
  MSGPROPID aMsgPropId[NUMBEROFPROPERTIES];  
  PROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];  
  HRESULT aMsgStatus[NUMBEROFPROPERTIES];  
  HANDLE hQueue = NULL;                          // Queue handle  
  HRESULT hr = MQ_OK;                            // Return code  
  
  // Specify message properties to be set.  
  WCHAR wszMessageBody[] = L"Message sent in an internal transaction.";  
  aMsgPropId[cPropId] = PROPID_M_BODY;       
  aMsgPropVar[cPropId].vt = VT_VECTOR | VT_UI1;   
  aMsgPropVar[cPropId].caub.pElems = (LPBYTE)wszMessageBody;  
  aMsgPropVar[cPropId].caub.cElems = sizeof(wszMessageBody);  
  cPropId++;  
  
  aMsgPropId[cPropId] = PROPID_M_LABEL;       
  aMsgPropVar[cPropId].vt = VT_LPWSTR;   
  aMsgPropVar[cPropId].pwszVal = L"Single transactional test message.";  
  cPropId++;  
  
  // Initialize the MQMSGPROPS structure.  
  msgprops.cProp = cPropId;                      // Number of message properties specified  
  msgprops.aPropID = aMsgPropId;                 // IDs of the message properties  
  msgprops.aPropVar = aMsgPropVar;               // Values of the message properties  
  msgprops.aStatus  = aMsgStatus;                // Error reports  
  
  // Open the transactional queue to send a message.  
  hr = MQOpenQueue(  
                   wszDestFormatName,           // Format name of the destination queue  
                   MQ_SEND_ACCESS,              // Access mode  
                   MQ_DENY_NONE,                // Share mode  
                   &hQueue                      // OUT: Handle to the queue  
                   );  
  if (FAILED(hr))  
  {  
    return hr;  
  }  
  
  // Send the message to the destination queue.  
  hr = MQSendMessage(  
                     hQueue,  
                     &msgprops,  
                     MQ_SINGLE_MESSAGE  
                     );  
  if (FAILED(hr))  
  {  
    MQCloseQueue(hQueue);  
    return hr;  
  }  
  
  // Close the queue.  
  hr = MQCloseQueue(hQueue);  
  
  return hr;  
}