But in this case after email is sent someone may turn off server and then that information will not be stored in DB.
This is not something you can 100% cover in code.
It's always possible that the server loses power exactly between the "send" and "confirm it being sent" steps. You can't write code that forces the machine to stay powered for longer than it physically is.
If you instead invert the steps, and first store the confirmation and only then send the email, then you run the risk (when the power goes out) of having registered an email as sent but not actually having sent it.
The simple question becomes: is it better to have sent an email twice, or to have sent no email at all?
In distributed systems, there are only two possible approaches:
- Send at most once
- Send at least once
In either scenario, you'd ideally send your message/command exactly once. The distinction between them is related to what should happen if the scenario is not ideal, i.e. if a problem occurs.
In "send at most once", you accept that it's better to not send a message/command than it is to send it twice. Compared to the other scenario, this one is rarely used, only in cases where taking an action twice is something that must be avoided at all costs (e.g. medical equipment that provides dosages, credit card transactions, ...)
"Send at least once" is the more common scenario, which accepts that it's better to mistakenly send a message/command more than once than it is to never send it at all. This is the better choice for scenario's where there is no real consequence from sending something twice. The extra bandwidth used is negligible, receiving an email twice is a minor glitch with no real consequence.
Eventual consistency is founded on the "at least once" principle, as it entails retrying something until it finally succeeds. If you retry something, that inherently means you try something more than once. If you try something more than once, it's inherently possible that more than one of those attempts succeeded (possibly without you knowing), and thus it's plausible for something to be done more than once.
There is no such thing as "send exactly once without fail". More broadly, there is no such thing as "do without fail".
If you're struggling to find an example of how your system might ever fail, consider what would happen if a nuclear missile or planetkiller asteroid were to hit your server park.