Focus on the user! All your development efforts want to provide the best UX possible.
The first question is, why do you need messages at all?
- In case of a successful request, you want the user to know that his request was successfully executed.
- In case of an erroneous request, you can distinguish: if the request may be altered by the user to turn into a successful request, then show a helpful error message (e.g. a simple form submission). If the request may not be altered by the user, be as informative as possible why the request failed (e.g. "Couldn't execute as service XY is not available. Please contact support etc.").
Easy: Erroneous request that may be altered:
In case of an erroneous request where the user may alter the request, don't save it in the session and directly render the page where the user may correct his request.
Difficult: Successful request or erroneous request that may not be altered:
Here you may generally want the user to not be able to execute the exact same request again after hitting F5 or taking similar actions, hence you redirect the user. In this case I personally favor the solution with a flash messages component (see Symfony Docs or Zend Docs for an example). In general, this technique does not lead to race conditions if your applications meets these assumptions:
- Your HTTP requests fired from the browser are executed fast. A user does not have a real chance of firing a second request in the meantime.
- Your AJAX calls either do not influence the flash messages - or, if you return structured data (XML, JSON) you may include a special section for flash messages, that are then being rendered by Javascript.
Now, to minimize error rates you can do the following:
- Store the timestamp when you added the flash message. Don't display old messages (e.g. > 1 minute). A mobile user may loose connection and then retry. What state does he expect the application to be in?
- Don't ever let the HTTP requests between your user and your server take long. If you need to perform long computations, try offloading things to a background worker and show the status of processing to the user.
Summing up: If you have general good practices concerning your HTTP communication in place, then the user is unlikely able to mess up flash messages. Weigh the pros and cons and focus on the user, not the complexity of your implementation, as there are methods to cope with that.