Ответ 1
Я должен уважительно не соглашаться: транзакционные системы не являются автоматическими и исключительно двигателями баз данных, совсем наоборот...
Я реализовал механизм транзакций приложения (в .NET), который отличается от транзакции базы данных. На самом деле это довольно просто (несколько часов работы, включая набор unit test). Он полностью написан на С# без каких-либо зависимостей от любой функциональности базы данных или любого другого компонента. Но сначала какой-то контекст...
Эта функция, не связанная с базой данных, существует в нескольких проявлениях на платформе Java, таких как EJB, ESB, JMS и часто в сочетании с BPM. Некоторые из этих проявлений используют базовую базу данных, но не всегда и не по необходимости. Другие платформы имеют сопоставимые проявления, такие как MSMQ.
Большинство устаревших систем управления версиями НЕ реализуют семантику транзакций ACID. Как сказал ддаа, CVS не только Subversion (его преемник). В Visual Source Safe нет. Если вы исследуете Subversion, вы можете найти сравнительные диаграммы, которые указывают на это.
Теперь для критической точки транзакция базы данных или ее эквивалент не гарантирует безопасную бизнес-логику. Хотя я люблю Subversion, иронически является отличным примером этого факта.
Вы можете использовать Subversion религиозно, а также автоматическую сборку script (одну команду, которая компилирует, тестирует и упаковывает ваше приложение) и по-прежнему фиксирует разбитую сборку в репозитории управления версиями. Я видел это неоднократно. Конечно, это еще проще с инструментами управления версиями, не связанными с ACID, такими как VSS. Но многим кажется удивительным, что это возможно с помощью таких инструментов, как Subversion.
Позвольте мне рассказать о сценарии. Вы и коллега разрабатываете приложение и используете Subversion для репозитория управления версиями. Вы оба кодируете и время от времени отправляете в репозиторий. Вы делаете несколько изменений, выполняете чистую сборку (перекомпилируете все исходные файлы), и все тесты проходят. Итак, вы совершаете свои изменения и возвращаетесь домой. Ваш коллега работает над своими собственными изменениями, поэтому он также запускает чистую сборку, видит, что все тесты проходят, и записывается в репозиторий. Но, ваш коллега затем обновляется из репозитория, делает еще несколько изменений, запускает чистую сборку, и сборка взорвалась на его лице! Он снова возвращает свои изменения, обновления из репозитория (просто чтобы убедиться) и обнаружил, что чистая сборка все еще взрывается! Ваш коллега тратит следующие пару часов на устранение неполадок сборки и источника, и в итоге находит изменения, которые вы сделали до того, как вы ушли, что приводит к сбою сборки. Он увольняет вам неприятное письмо и ваш взаимный босс, жалуясь, что вы сломали сборку, а затем небрежно отправились домой. Вы приходите утром, чтобы найти своего коллегу и своего босса, ждущего вашего стола, чтобы выкрикнуть вас, и все остальные смотрят! Таким образом, вы быстро запускаете чистую сборку и показываете, что сборка не сломана (все тесты проходят, как и вчера).
Итак, как это возможно? Это возможно, потому что каждая рабочая станция разработчика не является частью транзакции ACID; Subversion гарантирует только содержимое репозитория. Когда ваш коллега обновился из репозитория, его рабочая станция содержала смешанную копию содержимого репозитория (включая ваши изменения) и его собственные незафиксированные изменения. Когда ваш коллега выполнял чистую сборку на своей рабочей станции, он вызывал бизнес-транзакцию, которая НЕ защищалась семантикой ACID. Когда он вернул свои изменения и выполнил обновление, его рабочая станция затем сопоставила репозиторий, но сборка все еще была сломана. Зачем? Поскольку ваша рабочая станция также была частью отдельной бизнес-транзакции, которая также не была защищена семантикой ACID, в отличие от вашей фиксации в репозитории. Поскольку вы не обновили свою рабочую станцию, чтобы соответствовать репозиторию, прежде чем запускать свою чистую сборку, вы фактически не создавали исходные файлы, поскольку они существовали в репозитории. Если вы выполните такое обновление, вы обнаружите, что сборка также не работает на вашей рабочей станции.
Теперь я могу изложить свою первоначальную точку - транзакции имеют область/контекст, которые следует тщательно рассмотреть. Просто потому, что у вас есть транзакция ACID, это не означает, что ваша бизнес-логика безопасна, UNLESS объем/контекст транзакции ACID, а бизнес-логика соответствует ТОЧНО. Если вы полагаетесь на транзакцию ACID какой-то формы, но вы делаете НИЧЕГО в своей бизнес-логике, которая не покрывается этой транзакцией базы данных, тогда у вас есть пробел, который может позволить сопоставимую и катастрофическую ошибку. Если вы можете заставить свою бизнес-логику точно соответствовать транзакции с базой данных, тогда все будет хорошо. Если нет, то вам, вероятно, потребуется отдельная бизнес-транзакция. В зависимости от характера незащищенной логики вам может потребоваться реализовать свой собственный механизм транзакций.
Таким образом, обмен сообщениями может быть транзакционным, но область действия - это просто сообщение. Что касается вышеприведенного примера, контекст Subversion - это только отдельная фиксация в репозитории. Тем не менее, бизнес-транзакция представляет собой чистую сборку, которая включает в себя гораздо больший объем. Эта конкретная проблема обычно решается путем написания чистой сборки вместе с чистой проверкой, в идеале использующей непрерывную интеграцию (например, через CruiseControl или тому подобное). На рабочих станциях разработчика каждый разработчик должен выполнить упражнение для выполнения полного обновления (или даже чистой проверки) перед чистой сборкой.
Итак, чтобы повторить, каждая транзакция имеет область или контекст, который ограничивает его защиту. Коммерческие транзакции часто включают логику, которая превосходит возможности механизмов транзакций (таких как механизм базы данных), которые мы обычно используем. Возможно, вам придется изменить ситуацию. В редких случаях, возможно, даже имеет смысл написать свой собственный механизм транзакций, чтобы сделать это.
Я разработал переписку критической бизнес-системы для скромной компании из девяноста человек. Я счел необходимым реализовать такой механизм, и я нашел, что этот опыт будет легким, полезным и полезным. Я бы сделал это снова, возможно, немного более легко, но я всегда задавал вопрос, почему я не мог придерживаться транзакции базы данных.