Изоляция гарантирует, что параллельные транзакции не будут мешать друг другу. Это означает, что операции одной транзакции невидимы для других параллельных транзакций, пока исходная транзакция не будет зафиксирована. Без изоляции незавершенная транзакция одного пользователя может быть видна другому пользователю, что может привести к ошибкам acid test или путанице.
Почему важны транзакции базы данных?
AppMaster – это платформа нового поколения без кода для автоматизации бизнес-процессов и создания нативных приложений для веб и мобильных устройств с генерацией кода. Мы с вами довольно подробно проговорили все свойства ACID, их предназначение и сценарии использования. https://www.xcritical.com/ Как вы уже поняли, не все БД предлагают гарантии ACID, жертвуя ими ради более высокой производительности. Поэтому вполне может случиться, что на вашем проекте будет выбрана БД, не предлагающая ACID, и вам может понадобиться воплотить часть необходимого функционала ACID на стороне приложения.
Как управлять транзакциями базы данных и реализовывать свойства ACID
Запись на диск является слишком долгой операцией, и есть несколько способов решения этой проблемы. Я не хочу сильно вдаваться в теорию баз данных, но чтобы вы примерно понимали, в какую сторону глядеть, опишу в общих чертах, как разные БД решают проблему с durability. Давайте вспомним, как я описывал, что каждая операция имеет время вызова и время выполнения. Для удобства можно рассматривать вызов и выполнение как 2 действия. Тогда отсортированный список всех действий вызова и выполнения можно назвать историей БД.
Как бы я сейчас объяснил молодому себе… зачем существуют требования ACID для баз данных?
Слово кислота происходит от латинских слов acidus или acere , которые означают «кислый», поскольку одной из характеристик кислот в воде является кислый вкус (например, уксус или лимонный сок). В информатике акроним ACID описывает требования к транзакционной системе (например, к СУБД), обеспечивающие наиболее надёжную и предсказуемую её работу. Требования ACID были в основном сформулированы в конце 70-х годов Джимом Греем[1]. Транзакция это единая логическая операция, которая может состоять из одного или нескольких шагов. Например, транзакцией может быть перевод денежных средств между банковскими аккаунтами (снятие денег из одного и пополнение другого).
Что означает I в ACID и как это можно использовать
И чтобы избежать тех или иных нежелательных состояний, БД используют различные уровни изоляции – то есть, различные уровни защиты данных от нежелательных состояний. Глубокое понимание свойств ACID и их значения в транзакциях базы данных необходимо для создания мощной и масштабируемой инфраструктуры приложений. Объединив мощь no-code платформы AppMaster с подходящей СУБД, вы сможете эффективно реализовать свойства ACID в транзакциях базы данных и следовать передовым практикам для достижения надежного и согласованного управления данными.
Как понять, когда мне нужны гарантии ACID?
Пройдя много собеседований, выяснилось, что довольно приличная часть собеседующих, спрашивавших или как-то затрагивавших тему транзакций и их работы, не знают как работают транзакции и что означает для разработчика термин изоляция. Вплоть до архитектора в одной очень большой российской компании, для которого выводы, использованные мною для формулирования решения при прохождении архитектурной секции оказались чем-то вроде бреда. Пока готовится вторая статья (Миллиард абитуриентов МИРЭА 2), можно отвлечься и разобрать тему, продемонстрировать разработчикам что означает для них I в ACID.
Транзакции пришли, чтобы спасти нас
Выбор правильной СУБД играет решающую роль в обеспечении соблюдения свойств ACID транзакций вашей базы данных. Как упоминалось ранее, AppMaster легко интегрируется с базами данных, совместимыми с PostgreSQL, открывая ряд преимуществ, связанных с соответствием требованиям ACID. При выборе СУБД вам следует оценить ее способность поддерживать управление транзакциями, производительность, масштабируемость, безопасность и совместимость с существующими приложениями и инфраструктурой.
В этом шаблоне распределённая транзакция выполняется асинхронными локальными транзакциями во всех связанных микросервисах. Микросервисы связываются друг с другом через шину событий („event bus“). Если какой-либо микросервис не может завершить свою локальную транзакцию, другие микросервисы выполнят компенсационные транзакции для отката изменений. Если мы знаем, что некая функция или программа идемпотентна, то это значит, что мы можем и должны пробовать повторить её вызов в случае ошибки. А мы просто обязаны быть готовы к тому, что какая-то операция выдаст ошибку – учитывая, что современные приложения распределены по сети и железу, ошибка должна рассматриваться не как исключение, а как норма.
- А мы просто обязаны быть готовы к тому, что какая-то операция выдаст ошибку – учитывая, что современные приложения распределены по сети и железу, ошибка должна рассматриваться не как исключение, а как норма.
- Но что с одного счета списалось, а на другой пришло — это БД уже не проверит.
- Почему бы не сохранить записи об уведомлении в СУБД, а дальше уже по одному отправлять и контроллировать процесс отправки?
- Даже если там внутри было 10 запросов, вы можете спать спокойно — сломался один, откатятся все.
- Атомарность — это свойство, которое гарантирует, что транзакция либо будет полностью завершена, либо не будет выполнена вообще.
Свойства ACID (атомарность, согласованность, изоляция, долговечность)
Ответ на изначальный HTTP-запрос GET может включать в себя заголовок ETag для последующих запросов PUT со стороны клиента, который тот может использовать в заголовке If-Match. Для методов GET и HEAD сервер отправит обратно запрошенный ресурс, только если он соответствует одному из знакомых ему ETag. Для PUT и других небезопасных методов он будет загружать ресурс также только в этом случае. Если вы не знаете, как работает ETag, то вот хороший пример, с использованием библиотеки „feedparser“ (которая помогает парсить RSS и прочие feeds).
Уровни изоляции, такие как Read Uncommitted, Read Committed, Repeatable Read и Serializable, обеспечивают различные степени изоляции и могут быть выбраны в зависимости от конкретных потребностей приложения. Несмотря на то, что в нашем примере возможны только два состояния лока, использовать такую блокировку можно для много-этапных обработок, поэтому желательно обновлять запись, задавая исходное значение, которое мы ожидаем увидеть в момент изменения. Так можно избежать всяких странностей, да и отлаживать будет проще, так как сразу увидите проблему в логах. Необходимо отправлять уведомления массово нескольким пользователям. Можно конечно использовать кафку, но кафка не гарантирует, что сообщение будет точно обработано. Тем более что во время отправки сообщений в кафку может часть уйти, а часть не отправится – в итоге вы считаете, что сообщение ушло, а на деле – нет.
Любая ACID совместимая БД гарантирует, что будут применены изменения только успешных транзакций. Реляционные БД, о которых мы говорили выше, предоставляют разные уровни изоляции транзакций, и самые строгие из них гарантируют, что одна транзакция не сможет увидеть недействительные изменения, осуществлённые другой транзакцией. Возможно, данные станут согласованными в «ленивом» режиме при чтении („lazily at read time“). Во время выполнения транзакции параллельные транзакции не должны оказывать влияния на её результат. Изолированность — требование дорогое, поэтому в реальных базах данных существуют режимы, не полностью изолирующие транзакцию (уровни изолированности, допускающие фантомное чтение и ниже).
Хотя, конечно, зависит от того, что именно вы хотите делать с этими данными. Когда порядок выполнения транзакций имеет значение.Представьте себе, что ваша компания собралась переходить с мессенджера FunnyYellowChat в мессенджер FunnyRedChat, потому что в FunnyRedChat можно отсылать гифки, а в FunnyYellowChat – нельзя. Но вы не просто меняете мессенджер – вы мигрируете переписку вашей компании из одного мессенджера в другой. Вы делаете это, потому что ваши программисты ленились документировать программы и процессы где-то централизованно, и вместо этого всё публиковали в разных каналах в мессенджере.
Мы же говорим о конкурентности в значении одновременного доступа разных процессов к общим данным. И если падает запрос внутри транзакции, база откатывает всю транзакцию. Даже если там внутри было 10 запросов, вы можете спать спокойно — сломался один, откатятся все.
Атомарность гарантирует, что не получится такого, что адрес с телефоном сохранились, а сам клиент — нет. Это сделало бы базу неконсистентной, ведь у нас бы появились атрибуты, «висящие в воздухе», никому не принадлежащие.
Я решил вас всё-таки познакомить с этим термином, потому что миновать его при изучении БД трудно, но теперь, когда вы знаете, что это, я хочу, чтобы вы поскорее про него забыли. Изоляция – это, в основном то, что и подразумевают люди, когда говорят об ACID в целом. И именно по этой причине я начал разбор этой аббревиатуры с изоляции, а не пошёл по порядку, как обычно делают те, кто пытаются объяснить эту концепцию.
Атомарность позволяет группировать запросы и показывать взаимосвязь между ними. И если происходит ошибка по одному из них, назад откатываются все. Также я, как мне кажется, привёл довольно мало конкретных примеров реализации тех или иных вещей в тех или иных БД – главным образом, из-за того, что я не хотел погрязнуть в деталях. Если вы знаете какие-то хорошие примеры, упомяните их в комментариях – пожалуйста, со ссылкой на документацию или исследование. Если вы нашли какие-то фактические ошибки – обязательно сообщите об этом в комментариях.