compensating transactions are useful - but they may not work in a long running transaction either. Its possible to end up with things "wrapped around the axel". You cannot go back and you cannot proceed.

This is a hard problem but the usual approach is to snapshot state you depend on at the beginning of your transaction, then apply your changes to a copy of the state. Before committing your long running edit, you compare your snapshot to the current state of the data. If it matches you may proceed. If it doesn't you throw the whole thing out and tell the user he'll have to start over.

This is common on flight booking systems if you take too long from finding your flight to booking it. Its just the nature of things.