Реферат: Версионность в Yukon

Получим то, что и ожидалось: x = 3, y = 3.

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

BEGIN TRAN

UPDATE tst SET y = -1 WHERE x = 3

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

Тип Описание Объект Режим Статус spid
TAB 1963154039 IX GRANT 52
RID 1:1357:2 72057594057326592 X GRANT 52
PAG 1:1357 72057594057326592 IX GRANT 52

Таблица 1

То есть картина совпадает с той, которую можно видеть при использовании предыдущей версии SQL Server или БД без поддержки версионности.

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

SELECT * FROM tst WHERE x = 3

И результат будет точно таким же: x=3, y=3. Если попробовать сделать то же самое на БД без включенной поддержки версионности, то второй запрос из первой транзакции не выполнится. Он будет ожидать фиксации или отката второй транзакции. То есть он попросту не сможет прочитать нужную запись, поскольку она заблокирована. Но в данном случае блокировка нисколько не мешает прочитать версию данных, существовавшую на момент начала выборки.

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

Если теперь зафиксировать изменения тестовой таблицы, произведенные второй транзакцией:

COMMIT TRAN

и сделать опять выборку тех же данных в транзакции номер один:

SELECT * FROM tst WHERE x = 3

то мы уже получим результат x = 3, y = (-1), феномен неповторимого чтения (non-repeatable read) в действии. Нам удалось дважды обратиться к одним и тем же данным из одной транзакции и получить различные результаты.

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

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

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

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

Если, например, в одном подключении выполнить часть транзакции, изменив в тестовой табличке одну запись, но не фиксировать транзакцию, удерживая тем самым блокировку…

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

BEGIN TRAN

UPDATE tst SET y=3 WHERE x=3

А в другой транзакции попытаться изменить другую запись…

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

BEGIN TRAN

UPDATE tst SET y=-1 WHERE x=4

COMMIT

То вторая транзакция не завершится, а подвиснет в задумчивости. Если же в этот момент взглянуть на блокировки, наложенные на таблицу tst:

Тип Описание Объект Режим Статус spid
PAG 1:1357 72057594057326592 IU GRANT 54
PAG 1:1357 72057594057326592 IX GRANT 53
RID 1:1357:2 72057594057326592 X GRANT 53
RID 1:1357:2 72057594057326592 U WAIT 54
TAB 1963154039 IX GRANT 54
TAB 1963154039 IX GRANT 53

Таблица 2

то можно наблюдать картину, характерную для самого обычного блокировочника, хотя версионности никто не отменял, в чем можно убедиться, выполнив в еще одной параллельной read committed-транзакции читающий запрос:

К-во Просмотров: 347
Бесплатно скачать Реферат: Версионность в Yukon