Является ли транзакционное поведение когда-либо необходимым за пределами баз данных?

Я бы не посмел сделать что-то сложное в базе данных без транзакций. Почти всегда есть простая в использовании встроенная команда. Но когда вы начинаете работать с другими постоянными данными, вы просто не получаете эту простую в использовании поддержки транзакций. Например,

  • файловые системы
  • веб-службы (никто из них я не использовал)

Даже в непостоянных данных часто бывает полезно отменить блок работы, следуя за исключением. Ни одна из стандартных структур данных, которые вы получаете с языком, не поддерживает транзакции.

Что я хотел бы знать, почему базы данных являются особым случаем?

Есть ли полезные ссылки на тему транзакционного поведения вне базы данных?

Ответ 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 или тому подобное). На рабочих станциях разработчика каждый разработчик должен выполнить упражнение для выполнения полного обновления (или даже чистой проверки) перед чистой сборкой.

Итак, чтобы повторить, каждая транзакция имеет область или контекст, который ограничивает его защиту. Коммерческие транзакции часто включают логику, которая превосходит возможности механизмов транзакций (таких как механизм базы данных), которые мы обычно используем. Возможно, вам придется изменить ситуацию. В редких случаях, возможно, даже имеет смысл написать свой собственный механизм транзакций, чтобы сделать это.

Я разработал переписку критической бизнес-системы для скромной компании из девяноста человек. Я счел необходимым реализовать такой механизм, и я нашел, что этот опыт будет легким, полезным и полезным. Я бы сделал это снова, возможно, немного более легко, но я всегда задавал вопрос, почему я не мог придерживаться транзакции базы данных.

Ответ 2

Я думаю, что причина, по которой транзакции видны только в базах данных, заключается в том, что по определению системы, предоставляющие транзакции, называются базами данных. Это звучит кругом, поэтому я должен уточнить.

Поддержка транзакций - это функция, которая обеспечивает ACID свойства. В условиях непрофессионала это означает, что транзакция - это то, что позволяет 1. объединить несколько незаметных операций в один пакет, который либо преуспевает в целом, либо не работает в целом. 2. скрывать незафиксированные изменения для одновременных пользователей, чтобы 3. одновременные пользователи всегда имеют "последовательное" представление о системе.

Файловые системы традиционно предлагают механизм блокировки, но это отличается от предоставления транзакций. Однако все файловые системы обладают некоторыми атомными свойствами. Например, если у вас есть каталоги /a/ и /b/, и вы одновременно пытаетесь выполнить mv /a /b/a и mv /b /a/b, только одна из этих операций будет успешной, без ущерба для целостности. То, что вообще отсутствуют в файловых системах, - это возможность объединить несколько операций в один изолированный атомный пучок.

Ответ, упомянутый Subversion. Все здравомыслящие системы контроля версий имеют транзакции. При совершении нескольких файлов система либо полностью использует фиксацию, либо полностью отказывается от нее (кроме CVS, которую я не считаю нормальным). Причиной отклонения всегда является одновременное изменение. Разработчики системы управления версиями очень сознательно поддерживают базу данных.

Еще один ответ на вопрос упоминал системы обмена сообщениями как транзакционные. Я не читал связанный материал, но сам ответ касался только атомной доставки сообщений. Это не транзакции.

Я никогда не слышал о Clojure перед тем, как Brian C. упомянул об этом Вот. Мне кажется, что это действительно реализация транзакций вне контекста базы данных. Здесь основное внимание уделяется управлению concurrency, а не сохранению согласованности долговечных данных.

Итак, за исключением Clojure, кажется, что любая система, которая нуждается в транзакциях, либо использует базовую базу данных, либо превращается в базу данных.

Ответ 3

У современных файловых систем есть транзакции. Они просто прозрачны для конечного пользователя.

NTFS, XFS, JFS, EXT3 и ReiserFS все это делают, просто чтобы назвать несколько.

И это только внутреннее файловую систему. Многие операционные системы также поддерживают блокировку файлов (например, flock (2) в мире * NIX) с исключительными (записываемыми) и совместно используемыми (считываемыми) блокировками.

Изменить: Если вы думаете об этом, файловые системы не имеют уровней изоляции, таких как современные БД, потому что, как только вы закончите читать файл, вы традиционно закрываете его, если вы его не заблокировали. Затем вы снова открываете его, когда хотите написать ему.

Ответ 4

Clojure использует Программная транзакционная память, который использует транзакции для упрощения и безопасного написания многопоточных программ без ручных замков. Clojure имеет неизменяемые структуры данных с изменяемыми ссылками на них, а транзакции необходимы для изменения ссылок.

Ответ 5

Системы обмена сообщениями - еще один пример менеджеров ресурсов транзакций.

То есть вы можете убедиться, что потребитель сообщения успешно обрабатывает сообщение из очереди. Если обработка завершается с ошибкой, сообщение остается в очереди.

Кроме того, система обмена сообщениями может принимать участие в распределенной транзакции с другим менеджером ресурсов.

Дополнительная информация на

Ответ 6

Завершения Subversion являются транзакционными: они действительно атомарны, поэтому прерванная фиксация не оставляет репозиторий в несогласованном состоянии.

Ответ 7

У меня была ситуация, в которой мне нужно было обрабатывать файловую систему и базу данных как одну транзакционную единицу.

В моем случае мне нужно было только загрузить набор файлов в файловую систему. Я делал это, создавая случайные каталоги каждый раз, помещая там данные и сохраняя имя каталога в таблице базы данных. Поэтому вся моя работа с базой данных и имя каталога в таблице базы данных (= работа с файловой системой) могут выполняться в одной транзакции базы данных.

http://www.databasesandlife.com/atomic-operations-over-filesystem-and-database/