The MSMQ transport can handle messages with a Time-To-Be-Received (TTBR) set in two ways.
Native
When a message with a TTBR value is sent, NServiceBus translates the value to the native TTBR property of the MSMQ message. MSMQ continuously checks the Time-To-Be-Received of all queued messages. As soon as the message has expired, it is removed from the queue, and disk space gets reclaimed.
MSMQ enforces a single Time-To-Be-Received value for all messages in a transaction. If multiple messages enlist in a single transaction, then the TTBR from the first message will be used for all messages, leading to potentially unintentional message expiration. To prevent message loss, TTBR is not supported for endpoints with transaction mode SendsAtomicWithReceive
or TransactionScope
by default.
The MSMQ native TTBR implementation can be disabled for messages sent as part of a transaction. These messages rely on the non-native TTBR handling to ensure they are discarded when they are read by an endpoint, if the time to be received has expired. Messages sent outside of a transaction will still use the native TTBR capabilities built into the transport.
var transport = new MsmqTransport
{
UseNonNativeTimeToBeReceivedInTransactions = true
};
endpointConfiguration.UseTransport(transport);
Messages sent without the native MSMQ TTBR property set cannot automatically be cleaned up by MSMQ. They will remain in a queue until they are read. If they are read by an endpoint running on NServiceBus.Transport.Msmq version 1.0.x or below, messages can be processed even if the TTBR header has expired.
Non-native
NServiceBus also annotates outgoing messages with an NServiceBus.
header.
NServiceBus.Transport.Msmq version 1.0.x or below does not check the NServiceBus.
header.
NServiceBus.Transport.Msmq version 1.1 and above will consume a message without processing it if all of the following conditions are met:
- The message has an
NServiceBus.
headerTimeSent - The message has an
NServiceBus.
headerTimeToBeReceived - The cut-off time (Time Sent + Time To Be Received) has passed
The NServiceBus.
header is based on the clock of the sending machine but the cut-off time is compared to the clock on the receiving machine. There may be issues if the sending and receiving machines have clock synchronization drift. It is not advised to use TTBR values expressed in seconds and if small TTBR durations are used to account for clock drift. If the allowed clock drift is 15 seconds and the TTBR is 30 seconds the TTBR should be set to 45 seconds.
The transport can be configured to ignore the NServiceBus.
header on incoming messages.
var transport = new MsmqTransport
{
IgnoreIncomingTimeToBeReceivedHeaders = true
};
endpointConfiguration.UseTransport(transport);