Проблемы параллельного доступа.



 

При параллельном использовании транзакций могут возникать следующие проблемы:

 

  • потерянное обновление (lost update);
  • "грязное" чтение (dirty read);
  • неповторяющееся чтение (non-repeatable read);
  • фантомная вставка(phantom insert).

 

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

Предположим, происходит одновременная работа с таблицей ShopTable. Две транзакции открыты различными приложениями.

 

Транзакция 1 Транзакция 2 Cost
SELECT Сost FROM ShopTable WHERE PrName = ‘CD-R’; UPDATE ShopTable SET Сost = Сost*2 WHERE PrName = ‘CD-R’; SELECT Сost FROM ShopTable WHERE PrName = ‘CD-R’;               UPDATE ShopTable SET Сost = Сost*2 WHERE PrName = ‘CD-R’; 50 100 200

 

В транзакции 1 изменяется значение поля Cost, а затем в транзакции 2 также изменяется значение этого поля. В результате изменение, выполненное второй транзакцией, сделает результат неожиданным. Пусть начальное значение Cost = 50, тогда транзакция 1 изменит его на Cost = 100, после чего транзакция 2 увеличит значение поля ещё в два раза, в итоге Cost = 200.

 

2. «Грязное» чтение возникает, когда вторая транзакция видит не сохранённые изменения, сделанные первой транзакцией, после чего происходит откат первой транзакции.

 

Транзакция 1 Транзакция 2 BookName
SELECT BookName FROM Books WHERE SerialNum = “1234”; UPDATE Books SET BookName = “Азбука” WHERE SerialNum = “1234”; ROLLBACK WORK; SELECT BookName FROM Books WHERE SerialNum = “1234”; “Обломов” “Азбука” “Азбука” “Обломов”

 

В транзакции 1 изменяется значение поля Cost, а затем транзакция 2 выбирает значение этого поля. После этого происходит откат транзакции 1. В результате значение, полученное второй транзакцией, будет отличаться от реального значения, хранимого в базе данных.

 


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

 

Транзакция 1 Транзакция 2 Balance
SELECT Balance FROM BTable WHERE UserID = 1; UPDATE BTable SET Balance = Balance - 1000 WHERE UserID = 1; SELECT Balance FROM BTable WHERE UserID = 1; SELECT Balance FROM BTable WHERE UserID = 1; 2000 1000 1000

 

В транзакции 2 выбирается значение поля Balance, это значение используется для расчетов. В это время транзакция 1 изменяет поля Balance. При повторной попытке выбора значения из поля Balance в транзакции 2 будет получен другой результат. Пример: считывается информация о состоянии счета клиента банка, проверяется, достаточно ли средств на счету для выполнения какой-либо операции. В это время другая транзакция переводит деньги на другой счет. Следовательно, данные первой транзакции являются ошибочными, при повторном считывании данных будет получен другой результат, операцию проводить нельзя.

 

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

 

Транзакция 1 Транзакция 2  
INSERT ShopTable (PrName, Cost) VALUES (rake, 1000); SELECT AVG(Cost) FROM ShopTable; SELECT AVG(Cost) FROM ShopTable;  

 

В транзакции 2 выполняется запрос, использующий все значения поля cost. Затем транзакция 1 выполняет вставку новой строки, после этого повторное выполнение запроса в транзакции 2 выдаст другой результат.

При этом, если выполняемый запрос выбирает не все значения поля cost, а значение только одной строки таблицы, то выполнение оператора INSERT не приведет к ситуации фантомной вставки.

 


Блокировки и уровни изоляции

 

Для предотвращения конфликтов SQL сервер может ограничить одновременный доступ к данным. Запреты на работу с данными называются блокировками. Для поддержки блокировок определены уровни изоляции, которые определяют, какие типы конфликтов допустимы. В табл. 1 перечислены уровни изоляции и операции, разрешенные на каждом уровне.

 

Табл. 1. Разрешенные операции:

 

Уровень изоляции Потерянное обновление «Грязное» чтение Неповторяющееся чтение Фантомная вставка
READ UNCOMMITED нет да да да
READ COMMITED нет нет да да
REPEATABLE READ нет нет нет да
SERIALIZABLE нет нет нет нет

 

1. READ UNCOMMITED (неподтвержденное чтение). Самый низкий уровень изоляции, поддерживается защита только от потерянного обновления. Если пользователь изменяет данные, другие пользователи не могут изменить их, пока первая транзакция полностью не завершится. Тем не менее, разрешено «грязное чтение», т.е. если первая транзакция запишет какие-то данные, вторая их прочитает, а потом первая транзакция будет отменена, то получится, что вторая транзакция прочитала данные, которые никогда не существовали.

2. READ COMMITED (подтвержденное чтение). Запрещено «грязное чтение»: если пользователь изменяет данные, другие пользователи не могут считать их, пока изменение (транзакция) полностью не завершится. Однако существует проблема неповторяющегося чтения: если первый пользователь начал работу и прочитал данные, после этого второй пользователь изменил эти же данные и успешно зафиксировал изменения – то первый пользователь будет продолжать работу с уже изменёнными данными.

3. REPEATABLE READ (повторяющееся чтение). Повторное чтение строки возвратит первоначально считанные данные, любые обновления, произведенные другими пользователями до завершения транзакции, запрещены. Тем не менее, на этом уровне могут возникать фантомы.

4. SERIALIZABLE (упорядоченность). Самый высокий уровень изоляции. Результат выполнения транзакций такой же, как если бы они выполнялись по очереди. Невозможны никакие ошибки параллельного доступа.


Дата добавления: 2018-06-27; просмотров: 302; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!