Программирование >>  Программирование баз данных 

1 ... 140 141 142 [ 143 ] 144 145 146 ... 346


Возможные нарушения в работе, предотвращаемые с помощью блокировок

Блокировки позволяют устранить четыре описанных ниже нарушения в работе.

Чтение незафиксированных данных.

Неповторяемое чтение.

Фантомы.

Потерянные обновления.

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

Чтение незафиксированных данных

Чтение незафиксированных данных происходит, если в транзакции считывается строка, модифицируемая в другой транзакции, которая еще не завершена. Если транзакция, начатая первой, завершится успешно, то, по-видимому, внесенные в ней изменения останутся неизменными и проблема не возникнет. Но что произойдет, если будет выполнен откат транзакции, в которой были модифицированы данные, считанные в другой транзакции? При этом будет обнаружено, что считаны данные, ставшие результатом транзакции, которая фактически не оставила никаких следов в базе данных!

Рассмотрим на примере, показанном в табл. 12.1, как возникает ошибка, связанная с чтением незафиксированных данных.

Таблица 12.1. Пример того, как возникает ошибка, связанная с чтением незафиксированных данных

Q Исходное Незафиксирован- Значение,

транзакц Оператор транзакции 2 значение ное значение обнаруживаемое

данных данных в транзакции 2

BEGIN TRAN 3

UPDATE col = 5 BEGIN TRAN 3 5

SELECT anything SELECT @var = col 3 5 5

ROLLBACK UPDATE anything 3 5

SET whatever = @var

В табл. 12.1 нагл5щно показано, как возникает проблема.

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



К счастью, такое развитие событий невозможно, если используется заданный в СУБД SQL Server по умолчанию уровень изоляции транзакций (этот уровень изоляции, называемый READ COMMITTED, будет описан более подробно в разделе Определение уровня изоляции транзакции ).

Неповторяемое чтение

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

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

Таблица 12.2. Возможное развитие ситуации при возникновении неповторяемого чтения

Значение Данные таблицы, Значение, фактически переменной полученные находящееся

@Var в транзакции 1 в таблице

Транзакция 1

Транзакция 2

begin tran

NULL

select @Var = value from table

if @Var >=100

update value, set value = value - 100

(Завершение, ожидание освобождения блокировки и последующее продолжение)

begin tran

update value, set value = value - 50

end tran

125 125

125 (ожидание освобождения блокировки)

125 75

75 75

Либо -25 (если отсутствует ограничение check, предписывающее соблюдение условия > 0), либо ошибка 547 (если ограничение check задано)

Итак, снова возникает проблема. В транзакции 1 было выполнено предварительное считывание данных (а в некоторых случаях рекомендуется именно такая организация работы приложения) для проверки того, что обрабатываемое значение является дейст вительным и выполнение транзакции может быть продолжено (поскольку количество денег на счете является достаточным). Но проблема заключается в том, что еще до выполнения оператора UPDATE в транзакции 1 удается выполнить в СУБД операцию модификации данных, относяшуюся к транзакции 2. Если на таблице не задано офаничение



CHECK, позволяющее предотвратить появление в столбце отрицательного значения, то остатку на счете действительно будет присвоено значение -25, даже несмотря на то, что это противоречит здравому смыслу, поскольку такая возможность должна была бьггь предотвращена благодаря использованию оператора IF в транзакции 1.

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

Создание ограничения CHECK и контроль за возникновением ошибки с кодом 547.

Применение параметра ISOLATION LEVEL, имеющего значение REPEATABLE READ или SERIALIZABLE.

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

Более полное описание уровней изоляции транзакции будет приведено ниже, а пока достаточно отметить, что при использовании значений уровней изоляции REPEATABLE READ или SERIALIZABLE велика вероятность возникновения большего количества проблем, чем может быть решено с их помощью. Тем не менее возможность применения этих значений исключать нельзя.

Фантомы

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

Предположим, что в базе данных представлена информация о служащих ресторана быстрого питания. На подобных предприятиях обычно имеется довольно значительное количество служащих, труд которых оплачивается по минимальной заработной плате, определенной правительством. Правительство только что выпустило постановление о повышении минимальной заработной платы с 6,25 до 6,75 доллара в час, поэтому необходимо обновить таблицу Employees, чтобы перевести всех тех, кто получает меньше 6,75 доллара в час, на новую минимальную заработную плату. Безусловно, программист не предвидит возникновения каких-либо сложностей и передает на вьшолнение следующий довольно простой оператор:

UPDATE Employees

SET HourlyRate =6.75

WHERE HourlyRate < 6.75

ALTER TABLE Employees

ADD ckWage CHECK (HourlyRate >= 6.75)

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



1 ... 140 141 142 [ 143 ] 144 145 146 ... 346

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика