Звучит как уродливая проблема и вызывает много вопросов, которые вы не сможете обсудить с SO. При чтении вашей проблемы у меня возникла следующая идея, и хотя она «пахнет» так же плохо, как и другие, перечисленные вами, она может помочь вам найти окончательное решение.
Во-первых, есть какая-то система блокировки, как описано в @ user580122, чтобы пометить / записать факт выполнения одной из этих транзакций. (Не забудьте включить какую-то периодическую автоматическую проверку, чтобы проверить потерянные или отмененные транзакции!)
Далее, для каждого изменения, которое вы вносите в базу данных, регистрируйте его каким-либо образом, либо в приложении, либо в отдельной таблице. Идея состоит в том, что, имея копию базы данных в состоянии X, вы можете в любое время повторно выполнить шаги, представленные пользователем.
Далее выясним, как использовать снимки базы данных. Читайте об этом в BOL; общая идея заключается в том, что вы создаете моментальный снимок базы данных, делаете с ним все, что хотите, и в конечном итоге выбрасываете его. (Доступно только в SQL 2005 и более поздних версиях, только в выпуске Enterprise.)
Итак:
- Пользователь приходит и инициирует одну из этих мета-транзакций.
- В базе данных отмечен флаг, показывающий, что происходит. Новая транзакция не может быть запущена, если она уже выполняется. (Опять же, проверяйте потерянные транзакции время от времени!)
- Каждое изменение, внесенное в базу данных, отслеживается и регистрируется таким образом, что его можно повторить.
- Если пользователь решает отменить транзакцию, вы просто отбрасываете снимок, и ничего не меняется.
- Если пользователь решает сохранить транзакцию, вы сбрасываете снимок, а затем немедленно повторно применяете зарегистрированные изменения к «реальной» базе данных. Это должно сработать, поскольку ваши требования подразумевают, что, пока кто-то работает над одним из них, никто другой не может касаться связанных частей базы данных.
Да, это конечно пахнет, и это может не относиться к вашей проблеме. Надеюсь, что идеи помогут вам что-то придумать.