I've solved this problem by adding a status field to my email objects/rows which can assume the values "Unsent, sending, sent, error". I guess it is a bit self-explanatory, but status values are set like this:
- Unsent: Default status - Sending: Message dispatched to broker - Sent: Send task/message ack'ed - Error: Send task/message any other exception
This of course assumes that your 5 000 emails are not ephemeral and are in a database.
If by "doesn't support any transactionality" you mean ack's aren't possible for one reason or the other then of course you have to go a slightly different route (pun somewhat intended) by publishing a "result" task/message and updating your database rows based on what comes back on this new "task_result" queue.