Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Название
Транзакции и обеспечение безопасности и параллельности в них
Введение
Транзакции - действия (CRUD), которые происходят при обращении в бд в одном методе/клиенте и т. д. Группа операций в БД
В ходе совершения операций транзакции возникают такие вопросы
Основная часть
Для решения данных были сформированы 4 принципа ACID:
ACID или 4 свойства транзакций
Рассмотрим же, какие были придуманы вещи для удовлетворения условиям выше:
Изоляция
Всего существует 4 вида изоляции:
1. SERIALIZABLE
При данном уровне изоляции каждая транзакция изолирована от другой. То есть изменения видны только локально (только в одной транзакции). При этом она позволяет совершать обновление одной и той же записи только один раз при параллельных транзакциях, что обеспечивает согласованность данных. Однако при получении таблицы с обновленной информацией и закомиченной транзакцией в параллельно запущенных с первой транзакциях будет видна старая версия таблицы для обеспечения безопасности. И, если попытаться вставить уже существующую запись, которую не видно в данной транзакции, то мы получим ошибку и все модифицирующие действия при комите транзакции будут отменены (rollback, откат произойдёт). Но при этом в транзакции, запущенной после коммита транзакции, зафиксировавшей изменения в таблице мы увидим уже обновленную таблицу. Для более подробного объяснения, понимания смотреть 1-ую ссылку из "Ссылки на используемые в статье материалы"
В транзакциях, использующих чтение, такой уровень изолированности не подойдёт потому, что не будут видны изменения, если транзакции были запущены параллельно с той, в которой были сделаны закомиченные изменения, которые мы хотим увидеть. Но такой уровень изолированности подойдёт, если мы часто модифицируем таблицу и хотим строгой и безопасной согласованности данных.
Фактически SERIALIZABLE работает так же, как и Repeatable Read, только он дополнительно отслеживает условия, при которых результат параллельно выполняемых сериализуемых транзакций может не согласовываться с результатом этих же транзакций, выполняемых по очереди
"+" данного уровня в том, что он обеспечит строгую и безопасную согласованности данных
"-" же данного уровня изолированности в том, что он может быть медленным из-за частых локов при модифицирующих операциях + возможна зваимная блокировка
2. READ_COMMITTED
В ReadCommited не накладывается блокировка на модифицирующую операцию параллельной транзакции, если одна из транзакций закоммитилась + будут видны все закомиченные изменения из незакомиченной тарнзакции. То есть при данном уровне изоляции можно бесконечно модифицировать один и тот же элемент из бд.
Пример:
"+" данного уровня в том, что он обеспечивает согласованность данных, хорош для чтения обновленной информации и довольно быстр из-за меньшего числа блокировок на модифицирующие операции
"-" же в том, что он не обеспечивает безопасности так, как парллельные транзакции могут изменять элемент сколько угодно раз при коммите другой параллельной транзакции,
и это может привести к печальным последствиям, как в примере.
3. REPEATABLE_READ
Данный уровень изоляции транзакции похож на SERIALIZABLE так, как фиксирует состояние базы, с которой она и начала, и все изменения фиксируует лишь внутри транзакции, не распространяя их на другие параллельные транзакции. В select запросе будут видны только данные, зафиксированные на момент начала транзакции. Команды UPDATE, DELETE, SELECT FOR UPDATE и SELECT FOR SHARE ведут себя подобно SELECT при поиске целевых строк: они найдут только те целевые строки, которые были зафиксированы на момент начала транзакции. Однако к моменту, когда они будут найдены, эти целевые строки могут быть уже изменены (а также удалены или заблокированы) другой параллельной транзакцией. В этом случае транзакция в режиме Repeatable Read будет ожидать фиксирования или отката первой изменяющей данные транзакции (если она ещё выполняется). Если первая изменяющая транзакция откатывается, её результат отбрасывается и текущая транзакция может продолжить изменение изначально полученной строки. Если же первая транзакция зафиксировалась и в результате изменила или удалила эту строку, а не просто заблокировала её, произойдёт откат текущей транзакции
Фантомное чтение vs неповторяющееся чтение
В неповторяющемся чтении задейстованы модификации только одной строки/задействована только одна строка.
В то время как в фантомном чтении несколько и там не видны изменения над строкой/строками.
Пример, показывающий разницу между :
Заключение
В данной статье была рассмотрена разница между различными типами транзакций и в каких ситуациях стоит лучше каждую использовать
Полезные ссылки
Отдельная благодарность
Nikita777-coder