Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Сравнение СУБД Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2 3 4 5   вперед  Ctrl      все
 Конфликт записи \ чтения  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1090
Старые песни о главном. Промурыжил много тем и тут и в гугле, но общая картина складывается какая то странная. Чтобы не обсуждать абстрактно, приведу пример (вырожденный, потом обобщу)

Есть таблица остатков (скажем денсредств) и 2 потока каждый из которых читает:
SELECT sum FROM account WHERE key = 5, допустим сумма равна 3-м, на сервере приложений добавляет к 3, свою сумму, скажем первый добавляет 2, второй добавляет 3, и пытается записать результат UPDATE account SET sum = result WHERE key=5. (правильный ответ, если что : 3+2+3 = 8). Предположим они идут параллельно, первый считал - второй считал - первый записал - второй записал.

Итак что будут делать (по умолчанию (!)) с repeatable read каждая из СУБД:

1. MS SQL на сколько я понимаю на первое чтение будет 3 и повесит S блокировку, на второе чтение будет 3 и повесит S блокировку - на первой записи значения 5 попытается конвертить S блокировку в X и повиснет, так как на втором чтении висит S блокировка, на второй записи значения 6 попытается конвертить S в X, также повиснет, после чего один из процессов пометится как deadlock (допустим 2-й), кинет exception, и попросит сервер приложений повторить 2-ю транзакцию, в итоге сначала запишется 5, при повторе запишется 8 все ОК.

2. PostgreSQL и Firebird - первое чтение будет 3, второе чтение будет 3, первая запись будет 5 и пройдет, вторая запись увидит что значение изменилось с начала транзакции и кинет exception, и "попросит" сервер приложений повторить, тот заново начнет транзакцию и запишет 8 - все ОК.

3. Самое веселое в Oracle, который как я понимаю сначала запишет 5, а потом запишет 6 и будет думать что все ОК. Хотя это не так.

Теперь замечания:

a) я так понимаю для 2 и 3 можно повторять поведение 1 при помощи SELECT FOR UPDATE, правда там будет U блокировка, то есть уже второе чтение повиснет и предотвратит deadlock,
ну или SELECT FOR SHARE - тогда поведение будет точь в точь как в пункте 1.
б) у 1 я так понимаю без "ручной" работы с timestamp'ом повторить 2-е поведение автоматически нет возможности. Хотя как я понимаю нет особой разницы какой exception будет deadlock или update conflict (я так понимаю второй все же чаще бывает, но ресурсы на блокировки зато не тратятся)
в) у 3 я так понимаю можно включить TIL SERIALIZABLE и он тогда будет вести себе как 1 или как SELECT FOR UPDATE в пункте а)

Понимаю что где-то заблуждаюсь (а может и везде), поэтому и спрашиваю в каком пункте я не прав.

ЗЫ: Да, я в курсе что UPDATE account SET sum = sum + 2 WHERE key = 5, UPDATE account SET sum = sum + 3 WHERE key = 5, даже при READ COMMITED дадут 8 (кстати во втором случае да или нет?), но тут вопрос что вычисление может быть сложнее, требовать что-то еще чем просто суммирование, поэтому этот пример привел чтобы не усложнять.

И еще такой вопрос:

Если есть SELECT x FROM t1 LEFT JOIN (SELECT SUM(f),j FROM t2 GROUP BY j) Q ON Q.j = t1.x, в блокировочниках (и SELECT FOR UPDATE), S-блокироки повесятся на всю таблицу t2, или только на те у которых j из таблицы t1. Потому как это получается зависит от построенного плана выполнения, если решит сделать predicate push down - блокировки будут только на нужные данные, если нет то на всю таблицу?
5 дек 13, 12:41    [15245438]     Ответить | Цитировать Сообщить модератору
 Re: Конфликт записи \ чтения  [new]
ScareCrow
Member

Откуда: Белый город
Сообщений: 17472
студент учи что такое транзакции,
5 дек 13, 15:47    [15247225]     Ответить | Цитировать Сообщить модератору
 Re: Конфликт записи \ чтения  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1090
ScareCrow
студент учи что такое транзакции,


Очень ценное замечание. Чтобы я без него делал даже не знаю...
5 дек 13, 15:57    [15247353]     Ответить | Цитировать Сообщить модератору
 Re: Конфликт записи \ чтения  [new]
Мимо пробегал...
Guest
Логика железная, кстати. Вспоминаю "Ералаш", там где 13*7=28.
5 дек 13, 16:00    [15247387]     Ответить | Цитировать Сообщить модератору
 Re: Конфликт записи \ чтения  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1090
Кстати если кто не понял расширю процесс:

первый начал транзакцию - второй начал транзакцию - первый считал - второй считал - первый записал - второй записал - первый коммитнул транзакцию - второй коммитнул транзакцию
5 дек 13, 16:01    [15247401]     Ответить | Цитировать Сообщить модератору
 Re: Конфликт записи \ чтения  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1090
Мимо пробегал...
Логика железная, кстати. Вспоминаю "Ералаш", там где 13*7=28.


Еще одно ценное замечание. Очень полезный форум. Надо почаще писать :)
5 дек 13, 16:03    [15247414]     Ответить | Цитировать Сообщить модератору
 Re: Конфликт записи \ чтения  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74930
автор
б) у 1 я так понимаю без "ручной" работы с timestamp'ом повторить 2-е поведение автоматически нет возможности. Хотя как я понимаю нет особой разницы какой exception будет deadlock или update conflict (я так понимаю второй все же чаще бывает, но ресурсы на блокировки зато не тратятся)


Неправильно понимаете. У 1 версионный режим существует аж с 2005 года.
5 дек 13, 17:26    [15248191]     Ответить | Цитировать Сообщить модератору
 Re: Конфликт записи \ чтения  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1090
pkarklin
автор
б) у 1 я так понимаю без "ручной" работы с timestamp'ом повторить 2-е поведение автоматически нет возможности. Хотя как я понимаю нет особой разницы какой exception будет deadlock или update conflict (я так понимаю второй все же чаще бывает, но ресурсы на блокировки зато не тратятся)


Неправильно понимаете. У 1 версионный режим существует аж с 2005 года.


Это да, я уже тоже заметил... А он как 3 или как 2 работает? В смысле кидает update conflict exception или просто перезаписывает (ну или там минимум \ максимум и т.п. как в oracle strams)...
5 дек 13, 17:42    [15248342]     Ответить | Цитировать Сообщить модератору
 Re: Конфликт записи \ чтения  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74930
Nitro_Junkie,

Transactions running under snapshot isolation take an optimistic approach to data modification by acquiring locks on data before performing the modification only to enforce constraints. Otherwise, locks are not acquired on data until the data is to be modified. When a data row meets the update criteria, the snapshot transaction verifies that the data row has not been modified by a concurrent transaction that committed after the snapshot transaction began. If the data row has been modified outside of the snapshot transaction, an update conflict occurs and the snapshot transaction is terminated. The update conflict is handled by the Database Engine and there is no way to disable the update conflict detection.
5 дек 13, 17:55    [15248453]     Ответить | Цитировать Сообщить модератору
 Re: Конфликт записи \ чтения  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1090
pkarklin
Nitro_Junkie,

Transactions running under snapshot isolation take an optimistic approach to data modification by acquiring locks on data before performing the modification only to enforce constraints. Otherwise, locks are not acquired on data until the data is to be modified. When a data row meets the update criteria, the snapshot transaction verifies that the data row has not been modified by a concurrent transaction that committed after the snapshot transaction began. If the data row has been modified outside of the snapshot transaction, an update conflict occurs and the snapshot transaction is terminated. The update conflict is handled by the Database Engine and there is no way to disable the update conflict detection.


То есть я так понимаю работает как 2? Тогда зачет мелкософту :)
5 дек 13, 18:04    [15248529]     Ответить | Цитировать Сообщить модератору
 Re: Конфликт записи \ чтения  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1090
Nitro_Junkie,

Правда как 3 он работать не умеет, судя по фразе
автор
there is no way to disable the update conflict detection


Другое дело зачем oracle так резолвит update conflict'ы мне не до конца понятно.
5 дек 13, 18:05    [15248545]     Ответить | Цитировать Сообщить модератору
 Re: Конфликт записи \ чтения  [new]
ScareCrow
Member

Откуда: Белый город
Сообщений: 17472
а как вы предлагаете их резолвить при оптимистичной блокировке?
5 дек 13, 18:17    [15248625]     Ответить | Цитировать Сообщить модератору
 Re: Конфликт записи \ чтения  [new]
Ivan Durak
Member

Откуда: Minsk!!!
Сообщений: 3795
ScareCrow
а как вы предлагаете их резолвить при оптимистичной блокировке?

ну постгря же подругому резолвит, причем тоже оптимистически
5 дек 13, 18:22    [15248659]     Ответить | Цитировать Сообщить модератору
 Re: Конфликт записи \ чтения  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1090
ScareCrow
а как вы предлагаете их резолвить при оптимистичной блокировке?


Кидать exception. Ну иметь этот вариант точно, потому как просто всегда записывать последнее это жесть...
5 дек 13, 18:23    [15248663]     Ответить | Цитировать Сообщить модератору
 Re: Конфликт записи \ чтения  [new]
kdv
Member

Откуда: iBase.ru
Сообщений: 30253
ScareCrow
а как вы предлагаете их резолвить при оптимистичной блокировке?

в Firebird/InterBase, в версионнике, snapshot может попытаться поменять измененные с момента его стартат данные, только если они были отменены по rollback.
То есть,
Tran1 - snapshot start
Tran2 - update X
Tran1 - update X - получаем lock conflict

Если Tran2 сделает Rollback, то Tran1 может повторить update
Если Tran2 сделает Commit, то Tran1 эту запись не обновит в принципе, потому что она "не видит" изменения, сделанного Tran2, в силу своего уровня изолированности. А раз не может видеть (видит только то, что было до действий Tran2), значит не может и изменить.
И перешибать значение 3 на что-то свое, зная, что там уже это значение изменено и закоммичено - как бы моветон.
Snapshot это как бы snapshot и есть. Другое дело, что стандартный RepeatableRead позволяет видеть фантомы...
5 дек 13, 18:27    [15248682]     Ответить | Цитировать Сообщить модератору
 Re: Конфликт записи \ чтения  [new]
ScareCrow
Member

Откуда: Белый город
Сообщений: 17472
автор
только если они были отменены по rollback.

эм? если что то Rollback - то этого как бы и нет.
5 дек 13, 18:29    [15248693]     Ответить | Цитировать Сообщить модератору
 Re: Конфликт записи \ чтения  [new]
ScareCrow
Member

Откуда: Белый город
Сообщений: 17472
и насколько я помню Firebird там это возможно только если указать wait у транзакции.
5 дек 13, 18:29    [15248696]     Ответить | Цитировать Сообщить модератору
 Re: Конфликт записи \ чтения  [new]
ScareCrow
Member

Откуда: Белый город
Сообщений: 17472
Ivan Durak
ScareCrow
а как вы предлагаете их резолвить при оптимистичной блокировке?

ну постгря же подругому резолвит, причем тоже оптимистически

эм?
http://www.postgresql.org/docs/9.3/static/transaction-iso.html
автор
If the first updater rolls back, then its effects are negated and the repeatable read transaction can proceed with updating the originally found row. But if the first updater commits (and actually updated or deleted the row, not just locked it) then the repeatable read transaction will be rolled back with the message
5 дек 13, 18:32    [15248706]     Ответить | Цитировать Сообщить модератору
 Re: Конфликт записи \ чтения  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1090
kdv
ScareCrow
а как вы предлагаете их резолвить при оптимистичной блокировке?

в Firebird/InterBase, в версионнике, snapshot может попытаться поменять измененные с момента его стартат данные, только если они были отменены по rollback.
То есть,
Tran1 - snapshot start
Tran2 - update X
Tran1 - update X - получаем lock conflict

Если Tran2 сделает Rollback, то Tran1 может повторить update
Если Tran2 сделает Commit, то Tran1 эту запись не обновит в принципе, потому что она "не видит" изменения, сделанного Tran2, в силу своего уровня изолированности. А раз не может видеть (видит только то, что было до действий Tran2), значит не может и изменить.
И перешибать значение 3 на что-то свое, зная, что там уже это значение изменено и закоммичено - как бы моветон.
Snapshot это как бы snapshot и есть. Другое дело, что стандартный RepeatableRead позволяет видеть фантомы...


Кстати да в, описанном мной примере, update conflict кидается не сразу, а по завершении 1-й транзакции, в надежде что эта транзакция rollback'ся хотя это как-то ИМХО чересчур оптимистично (в среднем процент rollback'ых транзакций не сильно большой), можно было бы и сразу кинуть. Я просто опустил этот момент, чтобы не усложнять ситуацию, и считал что транзакция начинается при первом чтении и коммитится сразу после записи.

А что касается фантомов, то, по идее, можно придумать (правда мегаизвращенный случай) когда его и в serializable'е можно получить.
5 дек 13, 18:34    [15248721]     Ответить | Цитировать Сообщить модератору
 Re: Конфликт записи \ чтения  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1090
ScareCrow
Ivan Durak
пропущено...

ну постгря же подругому резолвит, причем тоже оптимистически

эм?
http://www.postgresql.org/docs/9.3/static/transaction-iso.html
автор
If the first updater rolls back, then its effects are negated and the repeatable read transaction can proceed with updating the originally found row. But if the first updater commits (and actually updated or deleted the row, not just locked it) then the repeatable read transaction will be rolled back with the message


Чего же вы дальше не процитировали?:

But if the first updater commits (and actually updated or deleted the row, not just locked it) then the repeatable read transaction will be rolled back with the message

ERROR: could not serialize access due to concurrent update

because a repeatable read transaction cannot modify or lock rows changed by other transactions after the repeatable read transaction began.
5 дек 13, 18:36    [15248731]     Ответить | Цитировать Сообщить модератору
 Re: Конфликт записи \ чтения  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 54790

ScareCrow
насколько я помню Firebird там это возможно только если указать wait у
транзакции.

Точнее если не указать no wait, поскольку wait это режим по умолчанию.

Posted via ActualForum NNTP Server 1.5

5 дек 13, 18:37    [15248740]     Ответить | Цитировать Сообщить модератору
 Re: Конфликт записи \ чтения  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1090
Dimitry Sibiryakov,

Так все таки, а в Оракле что обычно делают?

SERIALIZABLE включают? Ручные блокировки FOR UPDATE используют? Смотрят на системную колонку версии ряда ?
5 дек 13, 18:46    [15248781]     Ответить | Цитировать Сообщить модератору
 Re: Конфликт записи \ чтения  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 54790

Nitro_Junkie
Так все таки, а в Оракле что обычно делают?

Говорят "фу, что это у вас за update conflict-ы, у нас вот такого дерьма нет".

Posted via ActualForum NNTP Server 1.5

5 дек 13, 18:51    [15248798]     Ответить | Цитировать Сообщить модератору
 Re: Конфликт записи \ чтения  [new]
Nitro_Junkie
Member

Откуда:
Сообщений: 1090
Dimitry Sibiryakov
Nitro_Junkie
Так все таки, а в Оракле что обычно делают?

Говорят "фу, что это у вас за update conflict-ы, у нас вот такого дерьма нет".


:) . А если серьезно? Им что жалко было такой режим сделать, для версионника это же не проблема? С учетом :

Oracle has chosen the harder-to-implement but infinitely more concurrent multi-versioning scheme.


ЗЫ: Правда при этом описание repeatable read прерывается, а до этого были только лучи ненависти к deadlock'а. И нигде описание что oracle будет делать в том случае, когда блокировочник кинет deadlock. Пойти что ли на oracle'овски подфорум, или меня там ногами запинают? :)
5 дек 13, 18:58    [15248831]     Ответить | Цитировать Сообщить модератору
 Re: Конфликт записи \ чтения  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 54790

Nitro_Junkie
А если серьезно?

Отрывают руки тем, кто пишет "а=5" вместо "а=а+2".

Posted via ActualForum NNTP Server 1.5

5 дек 13, 19:00    [15248835]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2 3 4 5   вперед  Ctrl      все
Все форумы / Сравнение СУБД Ответить