INFO: MSMQ and MTS Design Programming Considerations

ID: Q176307

The information in this article applies to:

SUMMARY

This article addresses programming and design considerations for using Microsoft Message Queue Server (MSMQ) with Microsoft Transaction Server (MTS) Transactions.

When you use MSMQ inside an MTS component, decide in advance if you need a single transaction for all MSMQ and MTS operations, use explicit flags for pTransaction, and use appropriate queue types.

MORE INFORMATION

1. Queues are assigned a transactional property when created. This property

   is not modifiable later. MQCreateQueue API (or the Create method in
   ActiveX) does not detect MTS transaction context to set
   PROPID_Q_TRANSACTION. You need to supply this flag when creating a
   queue.

2. Messages sent to a transactional queue can be sent to the Dead Letter
   Queue if there is no current transaction in the following scenario:

      If the queue properties can be accessed at Send time, the call to
      Send rejects this operation due to a queue type mismatch. This is an
      application error that will not route the message to the
      corresponding Dead Letter Queue. If the queue properties can not be
      accessed at Send time, for example, when you are send directly to a
      remote location, then the Send fails later and will be in the Dead
      Letter Queue.

3. Messages sent to a non-transactional queue can be sent to the XACT_DEAD
   LETTER_QUEUE if they are part of a transaction in the following
   scenario:

      If the queue properties can be accessed at Send time, the call to
      Send rejects the operation due to queue type mismatch. This is an
      application error and the message will not route to the corresponding
      Dead Letter Queue. If the queue properties cannot be accessed at
      Send time, for example, when you are sending directly to remote
      location, then the Send fails later and will be found in
      XACT_DEAD_LETTER_QUEUE.

4. A single MSMQ component can send both transactional and
   non-transactional messages.

5. When run under MTS, MSMQ code can detect and become part of the
   current MTS transaction. The determining factor is the pTransaction
   parameter in MSMQ Send/Receive calls.

      For example, when using ActiveX Send/Receive methods in
      Visual Basic, it automatically checks if there is an MTS
      transaction (and will become part of that transaction) when
      you do not specify any value for pTransaction.

PTransaction

PTransaction is a MSMQTransaction object or one of the following constants:

   MQ_NO_TRANSACTION: Specifies that the call is not part of a
   transaction.

   MQ_MTS_TRANSACTION: Default. Specifies that the call is part of the
   current MTS transaction.

   MQ_XA_TRANSACTION: Specifies that the call is part of an externally
   coordinated, XA-compliant transaction.

Using C API specify the behavior you need:

pTransaction

   Must be a pointer to a transaction object, a constant, or NULL. The
   Transaction object can be obtained internally from MSMQ (by calling
   MQBeginTransaction), or externally from Microsoft Distributed
   Transaction Coordinator (DTC).

   The constants include the following:

   MQ_NO_TRANSACTION

     Specifies that the call is not part of a transaction.

   MQ_MTS_TRANSACTION

     Specifies that the current MTS transaction is used to retrieve the
     message.

   MQ_XA_TRANSACTION

     Specifies that the call is part of an externally coordinated, XA-
     compliant transaction.

NOTE: NULL indicates the message is not retrieved as part of a transaction.

6. Using explicit values of pTransaction you can send both transactional

   and non-transactional messages from a single component.

   If the component is non-transactional before being put into an MTS
   package, and the component is marked with "Requires a Transaction" or
   "Requires a New Transaction," then the queue the messages are sent to
   must be transactional. This requires deletion and re-creation, or you
   need to adjust the flag passed to pTransaction parameter.

   If you mark an MTS component as "Supports Transactions," it allows
   sending both types of messages to the same queue. It is necessary to add
   programming logic to create and use the appropriate queue at the right
   time.

   You can determine if there is an MTS transaction in process and write
   conditional code using specific flags.

   Refer to the IObjectContext.IsInTransaction method in MTS help file.

7. Using DtcGetTransactionManager creates a transaction. This occurs
   regardless of whether the component is inside or outside MTS. The net
   effect is that transactional messages create a new DTC transaction
   even if run under MTS.

REFERENCES

MSMQ SDK Help: Send/Receive calls, pTransaction

MTS Help

(c) Microsoft Corporation 1997, All Rights Reserved. Contributions by Syed Yousuf, Microsoft Corporation

Additional query words: Viper Falcon

Keywords          : MQProg kbfaq
Version           : WINNT:1.0
Platform          : winnt
Issue type        : kbinfo

Last Reviewed: January 30, 1998