Re[2]: Версионность в Yukon
От: Merle Австрия http://rsdn.ru
Дата: 03.03.04 10:11
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Что за "вероятность неупорядоченности" и почему она сохраняется ? Ведь от фантомов snapshot избавляет?

Немного не так, Snapshot избавляет от фантомных чтений, но ряда других, не столь очевидных проявлений фантомов, и феноменов (аномалий) избежать, используя только Snapshot не получится.
Ссылку на один пример Синклер уже дал. Примечательно то, что в Юконе, при snapshot IL, данный сценарий отработает совершено корректно. И никаких нарушений последовательного выполнения транзакций не произойдет.

Так же, одной из классических аномалий, от которой snapshot не избавляет, и которую можно отнести к разновидности фантомов является Write Skew:
Допустим бизнес-логика требует, чтобы x+y<5, на данный момент x=1 и y=1, далее псевдокод:
-- для всех транзакций
SET TRANSACTION ISOLATION LEVEL SNAPSHOT

-- транзакция 1 (T1)
--
SELECT (X, Y)

-- надо добавить к X два, 
-- проверяем, что X + 2 + Y < 5
--
IF ((X + 2) + Y < 5) -- все в порядке Y(=1) + X(=1+2)<5
    UPDATE SET X=X+2

-- в этот момент стартует вторая транзакция
-- которой, в свою очередь, надо к Y добавить 2, естественно с проверкой.
--
SELECT (X, Y)

IF (X + (Y + 2) < 5) -- тоже все в порядке Y(=1+2) + X(=1)<5
    UPDATE SET Y=Y+2 -- так как SELECT(X, Y) выбрал последнюю 
                     -- зафиксированную версию X (=1)

-- ну и фиксируем обе транзакции в произвольном порядке.
-- 
COMMIT    -- T1

COMMIT    -- T2

В многоверсионной истории это выглядит примерно так:
R1(x,y),W1(x),R2(x,y),W2(y),C1..,C2
Как нетрудно догадаться, в результате этих упражнений X+Y будет равно 6, что не соответствует никакому сценарию последовательного выполнения этих транзакций.


А>И зачем нужны фиктивные изменения? Я никогда не слышал, чтобы при работе с ораклом приходилось что-то фиктивно менять, а это "версионник".

Ну, все-таки, Оракл не совсем версионник и в силу этого у него есть хинт FOR UPDATE, как раз для таких случаев, как Write Skew. Если в примере, приведенном выше, выборку SELECT (x,y), в Оракле, делать с хинтом FOR UPDATE, то все сразу станет мягким и шелковистым. Эффект от выполнения этих транзакций всегда будет строго последовательным.
Но, честные версионники такой возможности не имеют, например, в InterBase'е, на сколько мне известно, чтобы избежать подобных аномалий необходимо делать фиктивный update X и Y в обеих транзакциях, перед тем, как считывать их значения.
Если же взять первый пример, ссылку на который дал Sinclair, то там не спасет и FOR UPDATE, и фиктивный UPDATE.
В силу отсутствия предикатных блокировок у всех известных мне версионников, в том сценарии поможет только блокировка всей таблицы.

А>2. А как добиваются Serializable? Блокируется вся таблица?

Вся таблица блокируется только в случае отсутствия индексов, если же находится подходящий индекс, то блокируется диапазон значений (Key Range Lock), что гораздо эффективнее.
Впрочем, подходящую ссылку так же уже привели..
Мы уже победили, просто это еще не так заметно...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.