skip to Main Content

Let’s say I have 2 types of messages. MessageA and MessageB.

  • MessageA creates an entry in DB.
  • MessageB updates an entry in DB.

Most cases, MessageA is sent with long-interval with MessageB. However, there are some cases where both message are sent seconds apart from each other. It might happen that MessageA is still creating DB entry, but MessageB tries to update non-existent.

How to handle this kind of scenario? I understand there are 2 options:

  1. Retry / Dead Letter Queue – message is sent back to queue and retried again until it reaches max delivery count and moved to Dead Letter Queue
  2. Defer – message is deferred until it is explicitly read

Which is the best practice?

  • 1 seems to be good, but still can be the case it reaches max retries,
    but DB entry not yet created.
  • 2 seems to be good, but need to do additional coding and
    infrastructure (Redis and Background Task) for periodically checking
    deferred messages

2

Answers


  1. There is a third option for dealing with these kinds of race condition (which is not always possible, depending on the nature of the messages):

    1. When Message B arrives before Message A, store the message data within the receiving service in either a partial form or in a specific holding area.
    2. When Message A arrives, check whether there is Message B data for the same key and process the two messages together if there is.

    A practical example: Say we have a school database with Year Group and Student entities. To create a new student, a message is sent with all the student details. To create a new Year Group, a message is sent with a Year Group name and list of StudentIds that should belong to that year group.

    If the Year Group message is received before all the students are received, you can create a placeholder student entity with just the student ID (and perhaps a flag to identify that it is a placeholder).

    When the Student message is received, it can simply add or update the existing record, and fill in all the student details.

    If you had to choose one of the two options you listed, it depends:

    • Retry/Deadletter is certainly much simpler, but will only work if there is a relatively short maximum delay between the two messages arriving. It’s much more fragile.
    • Message deferral will be much more reliable. It doesn’t need to be all that complicated either – you don’t need Redis and background tasks, you can check for deferred Message B on receipt of Message A.
    Login or Signup to reply.
  2. For scenarios such as this, where message order is required, Service Bus provides a feature to ensure messages are processed in the order they were originally sent – Message Sessions.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search