# Транзакции

{% hint style="info" %}
**Транзакция** — это набор действий с данными, объединенный в логическую единицу. Она либо выполняется целиком, либо нет.
{% endhint %}

## Проблемы неизолированных транзакций <a href="#id-2" id="id-2"></a>

* **Потерянное обновление**

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

* **Грязное чтение**

Когда читаются данные, которые в этот момент изменяются транзакцией, а потом транзакция откатывается и данные исчезают.

* **Неповторяющееся чтение**

Когда несколько раз читаются данные, которые в этот момент изменяются транзакцией — каждый раз данные могут отказаться другими.

* **Фантомное чтение**

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

## Изоляция транзакций <a href="#id-2" id="id-2"></a>

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

* **Чтение неподтверждённых данных (read uncommitted)**

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

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

* **Чтение подтверждённых данных (read committed)**

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

* **Повторяемое чтение (repeatable read)**

Можно читать все изменения только своей транзакции. Данные, измененные другими транзакциями, недоступны. Остается только проблема фантомных чтений.

* **Сериализуемый (serializable)**

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

## ACID

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

### Атомарность (atomicity)

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

### Согласованность (consistency)

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

### Изолированность (isolation)

Гарантия того, что параллельные транзакции не будут оказывать влияния на результат других транзакций. Мы разобрались с изоляцией выше.

### Долговечность (durability)

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

Источники:

* <https://www.flenov.info/books/read/free-sql-book/116>
* <https://gb.ru/blog/acid-cap-transactions/>
