Что такое транзакция, ACID, CAP теорема и уровни изоляций транзакций простыми словами
Данный материал позволит вам подготовиться к собеседованию, освежить знания или познакомиться с такими терминами как транзакции, ACID и уровни изоляции.
Важно отметить, что речь пойдет о реляционных базах данных, которые наилучшим образом подходят для транзакций и соответствуют критериям ACID.
Транзакция
Транзакция в базе данных представляет собой последовательность операций, которые либо успешно завершаются все вместе, либо не выполняются совсем.
Этот подход обеспечивает надежность данных, предотвращая ошибки и искажения. В случае сбоя во время транзакции база данных откатывает все изменения, чтобы сохранить целостность данных.
Пример успешной транзакции — банковский перевод между двумя людьми. Данная транзакция включает две операции: списание средств с одного баланса и зачисление на другой.
Пример транзакции
У транзакции есть два исхода — rollback и commit.
Rollback — откат совершенных изменений в базе данных. Rollback возвращает БД в состояние до транзакции.
Commit — фиксация всех изменений, сделанных в рамках транзакции, и сохранение их в базе данных.
Пример rollback и commit
ACID
Чтобы транзакция успешно выполнялась в базе данных, она должна обладать следующими свойствами:
Atomicity (Атомарность) — свойство, обеспечивающее целостность транзакций. Либо выполняются все изменения, либо осуществляется rollback до первоначального состояния.
Consistency (Согласованность) — принцип, согласно которому база данных гарантирует, что после успешного завершения каждой транзакции, данные в ней остаются в согласованном состоянии. Другими словами, до и после выполнения транзакции данные остаются надёжными и достоверными. Например, в контексте банковского перевода это означает, что транзакция не приведёт к появлению отрицательного баланса на одном счете, и одновременно к положительному на другом. Таким образом, мы можем быть уверены в достоверности и корректности данных в базе.
Isolation (Изолированность) — свойство, гарантирующее, что выполнение одной транзакции не влияет на выполнение других. Каждая транзакция должна работать независимо от других, даже если они выполняются параллельно. Это предотвращает конфликты и сохраняет целостность данных.
Durability (Надёжность) — «что написано пером, не вырубишь топором». Это свойство гарантирует, что после успешного завершения транзакции изменения будут сохранены и доступны в БД. После того, как произошел commit транзакции, мы можем быть уверены, что изменения не будут отменены из-за какого-либо сбоя.
CAP теорема
Казалось бы, можно придерживаться свойств ACID и наслаждаться жизнью. Но жизнь не была бы такой сладкой без ограничений. Речь идет о CAP теореме, которая ограничивает нас в создании распределённых систем. Важно понимать, что теорема CAP и ACID не противоречат друг другу, а дополняют.
CAP теорема утверждает, что в распределенной системе невозможно одновременно обеспечить согласованность данных (Consistency), доступность (Availability) и устойчивость к разделению сети (Partition tolerance). Можно обеспечить только два из этих трёх свойств одновременно.
Таким образом, при проектировании и разработке распределенных систем приходится искать компромиссы между согласованностью данных, доступностью и устойчивостью к разделению сети, опираясь на требования конкретного приложения и его контекст использования.
Например, банковские операции требуют согласованности и доступности, в то время как сервис отчетности — согласованности и устойчивости к разделению. С другой стороны, рекламное объявление букмекерской компании требует доступности и устойчивости к разделению, где согласованность не столь важна.
Уровни изоляции
Взглянем поближе на понятие изоляции транзакций.
Изоляция обеспечивает возможность параллельной работы двух транзакций. Если не настроить уровни изоляции транзакций, исходя из потребностей проекта, то параллельно выполняющиеся транзакции смогут мешать друг другу, в результате чего в базе данных будут неактуальные данные.
Разберём 3 основных явления, которые могут случиться при работе с транзакциями.
Грязное чтение (dirty read).
Возникает, когда одна транзакция читает данные, изменённые или вставленные другой транзакцией, которая ещё не была завершена и может быть откатана.
Суть в том, что транзакция видит изменения другой транзакции до их окончательного фиксирования, что может привести к принятию решений на основе неподтвержденных данных.
Грязное чтение
Неповторяющееся чтение (non repeatable read).
Это ситуация, когда одна транзакция читает данные несколько раз в пределах одной транзакции, и в процессе этих чтений данные изменяются другой транзакцией.
В отличие от предыдущего пункта первая транзакция видит разные значения при каждом чтении одного и того же ряда данных внутри одной транзакции. Это может привести к непредсказуемым или некорректным результатам, так как данные могут измениться между последовательными чтениями.
Основное различие от грязного чтения состоит в том, что:
в случае грязного чтения транзакция видит изменения другой транзакции до их окончательного фиксирования, даже если эта другая транзакция в конечном итоге откатится;
в неповторяющемся чтении учитываются лишь завершённые транзакции.
Неповторяющееся чтение
Фантомное чтение (phantom read).
Случай, когда в рамках одной транзакции повторно выполняется запрос, возвращающий набор строк для некоторого условия, и обнаруживает, что набор строк, удовлетворяющих условию, изменился из-за другой транзакции, завершившейся за это время.
Здесь ключевое — набор строк, которые нужны для одной транзакции: он стал больше, меньше или исчез из-за другой транзакции.
Фантомное чтение
Существуют уровни изоляции транзакций, которые определяют, какие типы феноменов изоляции допускаются:
Read Uncommitted (Чтение незафиксированных данных): транзакция может читать данные, которые могут быть изменены другими транзакциями, но ещё не зафиксированы.
Read Committed (Чтение зафиксированных данных): транзакция читает только те данные, которые уже были зафиксированы другими транзакциями. Это предотвращает грязное чтение, но может допускать неповторяющееся чтение и фантомные чтения.
Repeatable Read (Повторяющееся чтение): транзакция читает данные, гарантируя, что прочитанные данные не будут изменены другими транзакциями до завершения самой транзакции. Это предотвращает неповторяющееся чтение, но может допускать фантомные чтения.
Serializable (Упорядочиваемость): самый строгий уровень изоляции, гарантирующий, что транзакции выполняются так, как если бы они выполнялись последовательно, без параллельного выполнения. Это предотвращает фантомные чтения, неповторяющееся чтение и грязное чтение, обеспечивая полную изоляцию транзакций.
Перед нами стоит выбор: скорость или надежность.
Чем выше требуется надежность данных, тем больше ресурсов необходимо для поддержания этого уровня. Решение зависит от потребностей проекта и бизнеса. Некоторые приложения могут жертвовать изоляцией для увеличения скорости, но важно помнить, что для критически важных данных необходимо выбирать более строгие уровни изоляции. Анализ требований и рисков поможет сделать правильный выбор и обеспечить оптимальное сочетание скорости и надёжности данных для вашего приложения.
Чем выше согласованность данных, тем ниже производительность системы
Итак, выбор правильного уровня изоляции транзакций в базе данных играет важную роль в обеспечении баланса между производительностью и целостностью данных.
Важно помнить, что не существует универсального уровня изоляции, подходящего для всех сценариев использования, поэтому необходимо тщательно оценить требования проекта и выбрать наиболее подходящий уровень для обеспечения оптимального баланса между производительностью и согласованностью данных.
Рассказываю о процессах разработки, системном и бизнес-анализе, а также о карьере в IT в telegram.