Проблемы параллельных транзакций и уровни изолированности

Параллельность.

В современных информационных системах работает, как правило, несколько пользователей одновременно. Соответственно, они одновременно выполняют различные операции с данными. СУБД, управляющая базой данных такой информационной системы, должна обеспечивать возможность такой одновременной работы.

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

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

· Проблема «грязного» чтения. Возникает в ситуациях, когда одна транзакция считывает данные, измененные другой, еще не зафиксированной транзакцией. Соответственно, в случае отката второй транзакции у первой останутся неверные данные. В качестве примера рассмотрим условную ситуацию. Предположим, что владелец счета из первого примера проверяет баланс через банкомат. Одновременно в банке выполняется большая операция пополнения счетов (скажем, начисляется заработная плата) и проверяемый счет уже пополнен, но в целом транзакция не завершена. Может оказаться так, что по какой-то причине пополнение не будет доведено до конца (из-за сбоя, из-за некорректности данных и т. д.) и вся транзакция будет откачена. В итоге владелец карты получит неверные сведения об остатке на момент их проверки.

· Проблема неповторяемого чтения. Возникает, когда одна транзакция неоднократно считывает данные, а другие транзакции их в это время меняют. Например, формируется отчет об остатках и оборотах по картам. Сначала подсчитывается остаток средств на начало периода, затем сумма поступивших средств, затем сумма списанных средств и, наконец, остаток на конец периода. Очевидно, что если в процессе этих подсчетов добавлять или удалять записи об операциях, то суммы не будут соответствовать друг другу и отчет получится некорректным.

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

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

0 – read uncommitted. На этом уровне транзакции изолируются слабее всего. Перевод названия этого уровня – «чтение незафиксированных» (данных) говорит о том, что изменения, вносимые одной транзакцией в базу данных, будут немедленно доступны для остальных. На этом уровне возможно и «грязное» чтение, и неповторяющееся чтение, и чтение «фантомов». Гарантируется только отсутствие потерянных обновлений – одновременный доступ нескольких транзакций к одним и тем же данным для их изменения исключается.

1 – read committed. Этот уровень, как следует из его названия, запрещает транзакциям читать незафиксированные результаты других транзакций. За счет этого исключаются проблемы «грязного» чтения. Возможность неповторяемого чтения и появления «фантомов» все еще остается.

2 – repeatable read. Название этого уровня, «повторяемое чтение» говорит о том, что на нем также исключается проблема неповторяемого чтения. То есть, считанные одной транзакцией данные защищаются от изменения или удаления другими транзакциями. Но появление «фантомов» все еще возможно.

3 – serializable. Это наивысший уровень изолированности, на русский его название можно перевести как «Упорядочиваемый», хотя встречается и вариант «сериализуемый». На этом уровне СУБД выполняет транзакции в таком порядке, чтобы результат их параллельного выполнения был эквивалентен последовательному выполнению по одной. Такой уровень исключает все проблемы одновременного доступа к данным.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: