Проблема потери результатов обновления
Проблемы параллельной работы транзакций
Каким образом транзакции различных пользователей могут мешать друг другу? Различают три основные проблемы параллелизма:
- Проблема потери результатов обновления.
- Проблема незафиксированной зависимости (чтение "грязных" данных, неаккуратное считывание).
- Проблема несовместимого анализа.
Рассмотрим подробно эти проблемы.
Рассмотрим две транзакции, A и B, запускающиеся в соответствии с некоторыми графиками. Пусть транзакции работают с некоторыми объектами базы данных, например со строками таблицы. Операцию чтение строки будем обозначать
, где
- прочитанное значение. Операцию записи значения
в строку
будем обозначать
.
Две транзакции по очереди записывают некоторые данные в одну и ту же строку и фиксируют изменения.
Транзакция A | Время | Транзакция B |
Чтение ![]() | ![]() | --- |
--- | ![]() | Чтение ![]() |
Запись ![]() | ![]() | --- |
--- | ![]() | Запись ![]() |
Фиксация транзакции | ![]() | --- |
--- | ![]() | Фиксация транзакции |
Потеря результата обновления |
Результат. После окончания обеих транзакций, строка содержит значение
, занесенное более поздней транзакцией B. Транзакция A ничего не знает о существовании транзакции B, и естественно ожидает, что в строке
содержится значение
. Таким образом, транзакция A потеряла результаты своей работы.
Проблема незафиксированной зависимости (чтение "грязных" данных, неаккуратное считывание)
Транзакция B изменяет данные в строке. После этого транзакция A читает измененные данные и работает с ними. Транзакция B откатывается и восстанавливает старые данные.
Транзакция A | Время | Транзакция B |
--- | ![]() | Чтение ![]() |
--- | ![]() | Запись ![]() |
Чтение ![]() | ![]() | --- |
Работа с прочитанными данными ![]() | ![]() | --- |
--- | ![]() | Откат транзакции ![]() |
Фиксация транзакции | ![]() | --- |
Работа с "грязными" данными |
С чем же работала транзакция A?
Результат. Транзакция A в своей работе использовала данные, которых нет в базе данных. Более того, транзакция A использовала данные, которых нет, и не было в базе данных! Действительно, после отката транзакции B, должна восстановиться ситуация, как если бы транзакция B вообще никогда не выполнялась. Таким образом, результаты работы транзакции A некорректны, т.к. она работала с данными, отсутствовавшими в базе данных.