The information in this article applies to:
- Microsoft Message Queue Server version 1.0
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
- 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.
- 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.
- 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.
- A single MSMQ component can send both transactional and
non-transactional messages.
- 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.
- 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.
- 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