Handling Duplicate Messages
When developing message processing systems there can be
scenarios where an identical message can be sent by an application more than
once. In computer science if an operation is able to handle multiple instances
of the same input without changing the result we say that it is idempotent. In Service
Bus brokered messaging we are able to create idempotent messaging channels by
leveraging the duplicate deletion functionality that is built into queues and
topics.
The Enterprise Integration Patterns website provides a description of
the Idempotent Receiver pattern here.
|
Duplicate message detection in queues and topics is based on
the MessageId property of the messages that are sent by the sending application
and a time window that is set on the queue or topic. When a message is created
using one of the static CreateMessage methods the string value of a new GUID
will be assigned to the MessageId property.
The following code will create 10 new messages and output their
MessageId values.
for (int i = 0; i <= 9; i++)
{
// Create a test message.
BrokeredMessage testMsg = new BrokeredMessage
("Test");
// Output the message ID
Console.WriteLine("Message
{0} has MessageId {1}", i, testMsg.MessageId);
}
|
The output from the code is shown below.

Detecting duplicate messages based on the default message ID
can be useful in scenarios where an application sending messages to a queue or
topic needs to ensure that exactly one message is delivered.
Consider the following code.
try
{
// Send a message to a queue.
sender.Send(msg);
}
catch (TimeoutException ex)
{
// Has the message been sent?
}
|
If the message is sent to the queue and a timeout exception
is thrown there may be no way for the sending application to know that the
message has been sent successfully. If the sending application chooses to
resend the message it can ensure at-least-once delivery. If the sending
application chooses not to resend the message it can ensure at-most-once
delivery. If the queue or topic that the message is being sent to is configured
to detect duplicate messages the client can retry sending the message and the
queue or topic will ignore any duplicates. This will ensure exactly-once
delivery of the message.
In some scenarios message duplication may occur before the
application places the message on the queue or topic. If a web service is
called by a client places a message on the queue there is a chance that the
client may make two calls to the service if a timeout exception occurs. As the
two messages created in the service will have different message IDs the
duplicate detection logic will not detect the second message as a duplicate. In
order for duplicate detection to work in these scenarios we must replace the
default message ID with an identifier that is linked to the content of the
messages we are sending. The next scenario will explore how this can be
implemented.