Undo may not always be possible or appropriate, but you do need to consider the edge case where an action cannot be applied fully, in which case a decision must be made about what to do. In OP's example, failure to roll back would grant the user points but no discount, which isn't a nice outcome.
Trying to achieve a "commit point" where changes become visible only at the end of all the updates is worth considering, but it's potentially much more complex to achieve. Your entire data model (such as database tables, including index) has to be adapted to support the kind of "state swap" you need.
Trying to achieve a "commit point" where changes become visible only at the end of all the updates is worth considering, but it's potentially much more complex to achieve. Your entire data model (such as database tables, including index) has to be adapted to support the kind of "state swap" you need.