Visual Basic Code Example: Sending a Message Using a COM+ 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

Message Queuing provides a way to use the context that is associated with the current COM+ object to send messages within a COM+ transaction. The COM+ context can then be used either to commit or abort a transaction that includes send operations.

Note

As in all send transactions, messages are not actually sent until the transaction commits, and the destination queue must be transactional.

When your application calls MSMQMessage.Send with a request to send a message within a COM+ transaction (the default), Message Queuing verifies that your application is running in the context of a COM+ transaction. If Message Queuing finds that no COM+ object is running or that the current COM+ object is not executing in a transaction, the message is sent as a nontransactional message. To avoid an attempt to send a nontransactional message to a transactional queue, which will fail, your application can call the IsInTransaction method to verify that the current COM+ object is executing in a transaction before sending the message.

If the current object is not transactional, your application can explicitly or implicitly create its own transaction for the message. In the following example, a single-message transaction is used if the current COM+ object is not participating in a transaction.

To send a message within a COM+ transaction

  1. Declare instances of MSMQQueueInfo, MSMQQueue, MSMQMessage, and a COM+ context.

  2. Use the GetObjectContext method to obtain the current COM+ context.

  3. Call MSMQQueueInfo.Open to open the transactional queue with send access. The following example creates a queue if one does not exist.

  4. Specify message properties.

  5. Send the message as part of a transaction. The following example first ascertains whether the current COM+ object is transactional. If the object is transactional (participating in a transaction), a COM+ transaction is specified. If the object is not transactional, the message is sent in a single-message transaction.

  6. Call MSMQQueue.Close to close the queue and free its resources.

  7. Commit or abort the transaction. The following example aborts the transaction within the function's error handler (SendError).

Code Example

To try this example in Microsoft® Visual Basic® (version 5.0 or 6.0), paste the code into the Declaration section of a form, press F5, and click the form.

Option Explicit  
  
' Declare the required objects.  
Dim qinfo As New MSMQQueueInfo  
Dim qSend As MSMQQueue  
Dim msg As New MSMQMessage  
Dim ctxObject As ObjectContext  
  
Public Function MQSend( _  
                       strSend As String _  
                       ) As String  
  On Error GoTo SendError  
  
  ' Get the context associated with the current COM+ object.  
  Set ctxObject = GetObjectContext()  
  
  '*************************************************************  
  ' Optional. Add code for database updates if needed.  
  '*************************************************************  
  
  ' Open a transactional queue with SEND access. The queue is  
  ' created if no such queue exists.  
  qinfo.PathName = ".\TransactionTestQueue"  
  qinfo.Label = "COM+ Transaction Test"  
  On Error Resume Next          'Ignore if the queue already exists.  
  qinfo.Create IsTransactional:=True  
  On Error GoTo SendError  
  Set qSend = qinfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)  
  
  ' Set message properties as needed.  
  msg.Body = "COM+ transactional test message"  
  msg.Label = "Test Message"  
  
  ' Ascertain whether the COM+ context is transactional (the current COM+  
  ' object is participating in a transaction) and send the message. Note  
  ' that this example sends the message within a transaction in   
  ' either case.  
  If (Not ctxObject Is Nothing) Then  
    If (ctxObject.IsInTransaction) Then  
      msg.Send qSend                     'Sending within a COM+ transaction by default  
    Else  
      msg.Send qSend, MQ_SINGLE_MESSAGE  'Sending in a single-message transaction  
    End If  
  Else  
    msg.Send qSend, MQ_SINGLE_MESSAGE  
  End If  
  
  ' Close the queue.  
  qSend.Close  
  
  ' Commit or abort the transaction.  
  If (Not ctxObject Is Nothing) Then  
    ctxObject.SetComplete  
  End If  
  
  Set ctxObject = Nothing  
  Exit Function  
  
  SendError:  
    If (Not ctxObject Is Nothing) Then  
      ctxObject.SetAbort  
    End If  
    Set ctxObject = Nothing  
    If Not qSend Is Nothing And qSend.IsOpen2 Then  
      qSend.Close  
    EndIf  
    MQSend = "SendFailure"  
End Function