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

StackOverflow https://stackoverflow.com/questions/296909

Вопрос

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

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

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

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

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

Это было полезно?

Решение

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

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

Эта функция, не связанная с транзакциями базы данных, существует в нескольких проявлениях на платформе Java, например, с EJB, ESB, JMS и часто в сочетании с BPM.Некоторые из этих проявлений используют базовую базу данных, но не всегда и не по необходимости.Другие платформы имеют аналогичные проявления, например MSMQ.

Большинство устаревших систем контроля версий НЕ реализуют семантику транзакций ACID.Как сказал ddaa, CVS этого не делает, а Subversion (его преемник) делает это.Visual Source Safe этого не делает.Если вы исследуете Subversion, вы можете найти сравнительные таблицы, которые подчеркивают это.

Теперь о критическом моменте: транзакция базы данных или ее эквивалент не гарантирует безопасную бизнес-логику.Хотя я люблю Subversion, по иронии судьбы, это отличный пример этого факта.

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

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

Итак, как это возможно?Это возможно, поскольку каждая рабочая станция разработчика не участвует в транзакции ACID;Subversion гарантирует только содержимое репозитория.Когда ваш коллега обновлялся из репозитория, его рабочая станция содержала смешанную копию содержимого репозитория (включая ваши изменения) и его собственные незафиксированные изменения.Когда ваш коллега запускал чистую сборку на своей рабочей станции, он вызывал бизнес-транзакцию, которая НЕ была защищена семантикой ACID.Когда он отменил свои изменения и выполнил обновление, его рабочая станция соответствовала репозиторию, но сборка все еще была сломана.Почему?Потому что ваша рабочая станция также была частью отдельной бизнес-транзакции, которая также НЕ была защищена семантикой ACID, в отличие от вашей фиксации в репозитории.Поскольку вы не обновили свою рабочую станцию ​​в соответствии с репозиторием перед запуском чистой сборки, вы фактически не собирали исходные файлы в том виде, в каком они существовали в репозитории.Если вы выполнили такое обновление, вы обнаружите, что сборка также не удалась на вашей рабочей станции.

Теперь я могу изложить свою первоначальную мысль: транзакции имеют область действия/контекст, которые необходимо тщательно учитывать.Тот факт, что у вас есть транзакция ACID, не означает, что ваша бизнес-логика безопасна, ЕСЛИ область/контекст транзакции ACID и бизнес-логика не совпадают ТОЧНО.Если вы полагаетесь на какую-либо форму ACID-транзакции базы данных, но делаете в своей бизнес-логике НИЧЕГО, что не покрывается этой транзакцией базы данных, то у вас есть пробел, который может привести к сопоставимой и катастрофической ошибке.Если вы можете заставить свою бизнес-логику точно соответствовать транзакции базы данных, тогда все в порядке.Если нет, то вам, вероятно, потребуется отдельная бизнес-операция.В зависимости от характера незащищенной логики вам может потребоваться реализовать собственный механизм транзакций.

Таким образом, обмен сообщениями может быть транзакционным, но областью действия является просто сообщение.Что касается приведенного выше примера, контекст Subversion — это только отдельная фиксация в репозитории.Однако бизнес-транзакция представляет собой чистую сборку, которая включает в себя гораздо больший объем.Эта конкретная проблема обычно решается путем написания сценария чистой сборки вместе с чистой проверкой, в идеале с использованием реализации непрерывной интеграции (например, через CruiseControl или тому подобное).На рабочих станциях разработчиков от каждого разработчика требуется проявлять дисциплину и выполнять полное обновление (или даже чистую проверку) перед чистой сборкой.

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

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

Другие советы

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

Поддержка транзакций — это функция, которая обеспечивает КИСЛОТА характеристики.С точки зрения непрофессионала это означает, что транзакция — это нечто, позволяющее 1.объединить несколько дискретных операций в один пакет, который либо будет успешным в целом, либо провалится в целом 2.скрыть незафиксированные изменения для одновременных пользователей, чтобы 3.одновременные пользователи всегда имеют «согласованное» представление о системе.

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

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

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

Я никогда не слышал о Кложур до Брайан С. упомянул об этом здесь.Мне кажется, это действительно реализация транзакций вне контекста базы данных.Здесь основное внимание уделяется управлению параллелизмом, а не поддержанию согласованности долговременных данных.

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

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

NTFS, XFS, JFS, EXT3 и ReiserFS подходят, и это лишь некоторые из них.

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

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

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top