54
|
TAB
|
|
1963154039
|
IX
|
GRANT
|
53
|
Таблица 2
то можно наблюдать картину, характерную для самого
обычного блокировочника, хотя версионности никто не отменял, в чем можно
убедиться, выполнив в еще одной параллельной read committed-транзакции читающий
запрос:
SET
TRANSACTION ISOLATION LEVEL READ COMMITTED
BEGIN
TRAN
SELECT * FROM tst
COMMIT
|
Этот запрос совершенно спокойно выполнится, никого не
потревожив, и вернет при этом состояние таблицы на момент, предшествующий
изменениям, так как ни одна из изменяющих таблицу транзакций на время
выполнения этого запроса еще не зафиксирована. Все дело в том, что обычно
версионник выполняет изменения данных примерно по такому сценарию:
Делается версионное сканирование таблицы, и
выясняется, какие записи необходимо изменить.
Предпринимаются попытки изменить отобранные записи.
Если запись изменилась с момента версионного скана, то
проверяется, не перестала ли она удовлетворять критерию отбора, и если не
перестала, то запись меняется, если перестала, то пропускается. (Некоторые
реализации применяют здесь более хитрые алгоритмы, но этот вопрос выходит за
рамки данной статьи).
Если запись меняется в настоящий момент, то сервер
дожидается конца изменений и опять-таки проверяет соответствие записи условиям
выборки.
То есть ожидание , если и происходит, то только из-за
того, что в процессе обновления встретилась запись, которая меняется в данный
момент.
Чистый же блокировочник работает немного по другому
сценарию. Сканирование данных ему не имеет смысла делать, так как все запросы
на чтение у него блокирующие. Поэтому он просто перебирает все записи в таблице
по очереди (напомню, речь идет о таблице без индексов), проверяя их на
соответствие условию выборки, и накладывая при этом блокировку обновления
(update lock). Такая блокировка совместима с блокировками чтения, но
несовместима сама с собой и с монопольными блокировками. Таким образом, читающим запросам подобный перебор не мешает, но другие блокировки обновления и
монопольные будут помехой этому запросу. Следовательно, если в момент перебора
в таблице монопольно заблокирована хотя бы одна запись (что и имеет место в
данном примере, так как запись была изменена, но транзакция еще не
зафиксирована), то рано или поздно изменяющий запрос до нее доберется и зависнет
на блокировке, ожидая фиксации «вражеской» транзакции.
Несмотря на возможность версионных запросов, Yukon все
равно при записи данных поступает как блокировочник, что и приводит к
вышеописанному эффекту.
Repeatable read
Уровень изоляции repeatable read в базе с включенной
поддержкой версионности работает точно так же, как и на базе без оной.
Совершенно спокойно накладываются и удерживаются должное время все положенные
по статусу разделяемые (share) блокировки. Да в общем-то, вряд ли тут вообще
что-то могло измениться. Но появилась одна полезная возможность: Если запрос
выполняется по базе с включенной поддержкой версионности, то при указании
оптимизатору хинта READCOMMITTED в читающем запросе, выборка будет версионной.
Возможность действительно довольно полезная - в связи с некоторыми
особенностями уровня изоляции snapshot.
Snapshot
Уровень изоляции snapshot, является чисто версионным, в отличие от предыдущего, чисто блокировочного, и вообще совершенно новым для
SQL Server.
Читающие запросы при этом уровне изоляции выполняются
так, как и положено им выполняться в честном версионнике при этом уровне
изоляции. Если вернуться все к той же тестовой табличке и в одном из
подключений начать транзакцию, в которой изменить какую-нибудь запись, но саму
транзакцию не фиксировать…
Рекомендуем скачать другие рефераты по теме: контрольная работа по математике класс, контрольные работы по математике.
Предыдущая страница реферата |
2
3
4
5
6
7
8
9
10
11
12 |
Следующая страница реферата