|
|
|
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
|
|||
|---|---|---|---|
|
#18+
Вопросик тут вспых. При апдейте, натыкающемся на закоммиченную новую версию записи, транзакция получит по лбу: Код: plaintext 1. Допустим, в таблице `t` изначально было вот это: Код: plaintext 1. 2. 3. 4. Если теперь сделать вот так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. - то получаю в session #1 Код: plaintext 1. 2. То же самое будет, если session #1 стартанёт транзакцию как NO record_version. Но при старте этой сессией вот так: Код: plaintext Так вот, вопрос: не было бы логичнее выдавать эту же ошибку и при старте в режиме read committed ? Ведь select ... for update with lock - он же не с будуна введён, а для апдейта . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.03.2014, 23:00:39 |
|
||
|
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
|
|||
|---|---|---|---|
|
#18+
ТаблоидВопросик тут вспых.А давай без вспыхов, сам объясни - почему это правильно ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.03.2014, 23:46:38 |
|
||
|
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
|
|||
|---|---|---|---|
|
#18+
Таблоид, а в чем вопрос? в том, что снапшоту чужие изменения видеть нельзя пожизненно, а RC - можно? Или вопрос в другом? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2014, 00:11:57 |
|
||
|
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
|
|||
|---|---|---|---|
|
#18+
kdv, нет, он просто не понимает, зачем WITH LOCK в RC тр-ции работает в режиме NO_REC_VER ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2014, 07:11:02 |
|
||
|
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
|
|||
|---|---|---|---|
|
#18+
hvladТаблоидВопросик тут вспых.А давай без вспыхов, сам объясни - почему это правильноЭто формально правильно, т.к. select стартовал RC и, когда запись стала ему доступной (при коммите другой трн), то он должен видеть закоммиченные изменения. Вот он и видит f01 = -200. Однако, select этот (session #1) дёргает запись для изменения . Когда он её нашёл, в ней было еще id = 2, f01= + 200 - она её именно такой видел. Когда же он её получил в распоряжение, то там оказалось f01= - 200. Если он теперь будет перетирать значение f01 чем-то другим (вместо выброса ошибки), то не похоже ли это на синдром LOST UPDATE ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2014, 09:11:40 |
|
||
|
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
|
|||
|---|---|---|---|
|
#18+
dimitrон просто не понимает, зачем WITH LOCK в RC тр-ции работает в режиме NO_REC_VERДа, я не понял этого, т.к. начал эксперимент с rc rec_ver. Ну так объясни мне, плз: почему snapshot, натыкаясь на обновлённую запись, НЕ позволяет произойти lost update и вываливает ошибку (что есть гут, КМК), а RC - запросто. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2014, 09:15:37 |
|
||
|
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
|
|||
|---|---|---|---|
|
#18+
Таблоид, снапшот в принципе не может перечитать измененные конкурентом данные, поэтому ошибка там неизбежна. В RC это возможно, в текущей реализации это позволяет режим NO_REC_VER. Я не понимаю, зачем ты приплетаешь тут lost update, ибо ситуация полностью аналогична как если бы наш селект+апдейт начал выполняться после коммита конкурента, а не до. Точно также имеем перезапись чужих изменений своими. Тебя это не беспокоит? Не хочешь поговорить об этом? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2014, 10:37:17 |
|
||
|
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
|
|||
|---|---|---|---|
|
#18+
WITH LOCK в первую очередь предназначен для сериализации доступа к общему ресурсу. Если он это сможет обеспечивать с минимумом конфликтов - тем лучше. Но Таблоиду почему-то принципы (читай: теория) вдруг стали важнее практики. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2014, 10:40:55 |
|
||
|
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
|
|||
|---|---|---|---|
|
#18+
ТаблоидКогда он её нашёл, в ней было еще id = 2, f01= + 200 - она её именно такой видел.Нет, он её такой не видел. Он увидел, что есть незакомиченные изменения и стал ждать коммита. И только потом прочитал запись. Дальше всё как обычно - RC имеет право видеть чужие изменения, сделанные после своего старта, а snapshot - не имеет такой возможности. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2014, 11:55:36 |
|
||
|
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
|
|||
|---|---|---|---|
|
#18+
dimitrВ RC это [ перечитывание изменённых конкурентом данных] возможно, в текущей реализации это позволяет режим NO_REC_VER. Я не понимаю, зачем ты приплетаешь тут lost update, ибо ситуация полностью аналогична как если бы наш селект+апдейт начал выполняться после коммита конкурента, а не до. Точно также имеем перезапись чужих изменений своими. Тебя это не беспокоит? Не хочешь поговорить об этом?Когда селект / апдейт стартует после чужого коммита - какие проблемы, всё ОК. Но когда он стартует *до*, молотит там что-то, а затем доходит до чужой залоченной записи и, дожидаясь её высвобождения, ТИХО перетирает - это для мну культурный шок. Такое только в орацле бывает... :-) А потому - да, этот Гондурас меня вдруг забеспокоил. Хочу поговорить об этом. Если начал выполняться некий "долгий стейтмент" в read committed, а затем он дошел до залоченной записи и застрял на ней, то это значит, что сначала он УВИДЕЛ её как подходящую под where-условие, и только затем попытался залочить. И если далее он её получит в изменённом виде (после commit'a конкурента), ПРОЧИТАТЬ её в новом виде - ради бога, но менять эту строку он не имеет права, это самый натуральный lost update. НЕЗАВИСИМО от того, какой там record_version. Я провёл тест с этой же табличкой, но для замедления использовал в session #1 запрос: update t set f01=33+0*(select count(*) from rdb$types,rdb$types,rdb$types) (и аналогичный с select for update). Результат такой: ВремяКтоДействие и результатT1session #1Стартовал в RC стейтмент select … from tmp where <cond01>. Либо стейтмент update tmp set … where <cond01>. T2session #2update tmp set f01 = <some_new_value> where id = :v_id - и эта запись подпадает под условие <cond01>T3session #1Доходит до записи с id = :v_id, которая подпадает под условие <cond01>, и затыкаетсяT4session #2commit;T5session #1Если стартовал select for update - выдаст новое содержимое записи (независимо от rec_version). Если новая версия перестала попадать под условие <cond01>, то НЕ выдаст эту строку. Если был update , то: 1) при NO REC_VER - ПЕРЕТРЁТ её содержимое (при условии, что новая версия продолжает подпадать под условие <cond01>); 2) при REC_VER - вывалит update conflict То же самое будет и при этом (действия в T2 & T1 из предыдущего примера поменяны местами):ВремяКтоДействие и результатT1session #2update tmp set f01 = <some_new_value> where id = :v_id T2session #1Стартовал в RC стейтмент select … from tmp where <cond01>. Либо стейтмент update tmp set … where <cond01>. T3session #1Доходит до записи с id = :v_id, которая подпадает под условие <cond01>, и затыкаетсяT4session #2commit;T5session #1Если стартовал select for update - выдаст новое содержимое записи (независимо от rec_version). Если новая версия перестала попадать под условие <cond01>, то НЕ выдаст эту строку. Если был update , то: 1) при NO REC_VER - ПЕРЕТРЁТ её содержимое (при условии, что новая версия продолжает подпадать под условие <cond01>); 2) при REC_VER - вывалит update conflict ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2014, 13:26:44 |
|
||
|
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
|
|||
|---|---|---|---|
|
#18+
dimitrWITH LOCK в первую очередь предназначен для сериализации доступа к общему ресурсу. Если он это сможет обеспечивать с минимумом конфликтов - тем лучше. Но Таблоиду почему-то принципы (читай: теория) вдруг стали важнее практики.Во-во! Именно на сериализации доступа я и получил гемор. Если есть документ, который надо перевести из статуса "Открыт" в статус "Закрыт", и к нему ломятся два и более аттача, то после успешного выполнения select for update в каждом аттаче надо еще раз проеверять содержимое поля "Статус": а не закрыт ли он уже ("только что") ? Ибо в селект этот выдаст строку в новом виде (с новым значением поля "Статус" и всех прочих) - тихо, без всякой ругани. Остановился пока на дебильном Код: sql 1. - выполнение его в RC обязательно вывалит ошибку, если было ожидание и конкурент успел обновить этот документ. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2014, 13:34:47 |
|
||
|
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
|
|||
|---|---|---|---|
|
#18+
hvladДальше всё как обычно - RC имеет право видеть чужие изменения, сделанные после своего старта, а snapshot - не имеет такой возможности. Видеть - да. А менять ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2014, 13:36:18 |
|
||
|
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
|
|||
|---|---|---|---|
|
#18+
ТаблоидЕсли начал выполняться некий "долгий стейтмент" в read committed, а затем он дошел до залоченной записи и застрял на ней, то это значит, что сначала он УВИДЕЛ её как подходящую под where-условиеНе надо фантазировать. Сначала читается и анализируется заголовок записи. Сама запись читается позже. Остальной бред я даже не читал ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2014, 15:14:43 |
|
||
|
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
|
|||
|---|---|---|---|
|
#18+
Таблоид это самый натуральный lost update. lost update - нормальная ситуация для rc. tr1. select tr2. select tr1 update tr1 commit tr2 update - проходит на ура. а свой select for update with lock можешь заменить на простой update set a=a ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2014, 15:40:35 |
|
||
|
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
|
|||
|---|---|---|---|
|
#18+
hvladСама запись читается позже.Хорошо: session #1 увидел заголовок. При no rec_version проверил, залочена ли она конкурентом. Оказалось - да, залочена, так что session #1 застрял на ней. Дальше session #2 закоммитил изменения, и session #1 тут же получил запись. ВИДЕТЬ запись в изменённом виде session #1, безусловно, ДОЛЖЕН, ведь это RC. Но сам стейтмент от session #1 начался *ДО* этого коммита от session #2, так почему он вправе еще и МЕНЯТЬ запись, перетирать её ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2014, 15:53:29 |
|
||
|
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
|
|||
|---|---|---|---|
|
#18+
kdvТаблоид это самый натуральный lost update. lost update - нормальная ситуация для rc. Код: plaintext 1. 2. 3. 4. Я же говорю про случай, когда: Код: plaintext 1. 2. 3. 4. 1) ОБЛОМ при rc REC_version и 2) ТИХОЕ ПЕРЕТИРАНИЕ при rc NO_rec_version kdvа свой select for update with lock можешь заменить на простой update set a=a ...Дык!.. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2014, 16:02:39 |
|
||
|
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
|
|||
|---|---|---|---|
|
#18+
ТаблоидКогда селект / апдейт стартует после чужого коммита - какие проблемы, всё ОК. Но когда он стартует *до*, молотит там что-то, а затем доходит до чужой залоченной записи и, дожидаясь её высвобождения, ТИХО перетирает а какая половая разница (с точки зрения lost update в случае RC транзакции) между двумя этими случаями? Почему lost update в первом случае ты считаешь нормальным, но бесишься во втором? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2014, 16:08:34 |
|
||
|
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
|
|||
|---|---|---|---|
|
#18+
ТаблоидИменно на сериализации доступа я и получил гемор. Если есть документ, который надо перевести из статуса "Открыт" в статус "Закрыт", и к нему ломятся два и более аттача, то после успешного выполнения select for update в каждом аттаче надо еще раз проверять содержимое поля "Статус": а не закрыт ли он уже ("только что") ? ты закрываешь пачку документов разом, что-ли? А нафига тут вообще что-то лочить? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2014, 16:11:51 |
|
||
|
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
|
|||
|---|---|---|---|
|
#18+
dimitrТаблоидКогда селект / апдейт стартует после чужого коммита - какие проблемы, всё ОК. Но когда он стартует *до*, молотит там что-то, а затем доходит до чужой залоченной записи и, дожидаясь её высвобождения, ТИХО перетираета какая половая разница (с точки зрения lost update в случае RC транзакции) между двумя этими случаями? Почему lost update в первом случае ты считаешь нормальным, но бесишься во втором?Да как это ?! Если коннект-2 закоммитил запись и *после* этого любой стартующий стейтмент коннекта-1 будет обламываться - это как тогда работать-то ?! Это всё шутка юмора, конечно. В текстах стандарта 2003 и 2006 я не вижу упоминания про т.н. "феномен-4" (P4), про который говорится тут . Но раз наступление этого "P4" блокируется при изменениях в rc rec_ver, то почему это же не сделано в rc NO_rec_ver ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2014, 16:24:05 |
|
||
|
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
|
|||
|---|---|---|---|
|
#18+
dimitrТаблоидИменно на сериализации доступа я и получил гемор. Если есть документ, который надо перевести из статуса "Открыт" в статус "Закрыт", и к нему ломятся два и более аттача, то после успешного выполнения select for update в каждом аттаче надо еще раз проверять содержимое поля "Статус": а не закрыт ли он уже ("только что") ? ты закрываешь пачку документов разом, что-ли? А нафига тут вообще что-то лочить?Нет, наоборот. Документы будут генериться 300 аттачами, они при этом будут в состоянии "НЕ закрыт". Также будет создано 30 аттачей, каждый из которых будет выбирать случайный (или "не очень") документ для закрытия. Столкновение лбами кого-то из этих 30 аттачей неминуемо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2014, 16:27:03 |
|
||
|
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
|
|||
|---|---|---|---|
|
#18+
ТаблоидНо сам стейтмент от session #1 начался *ДО* этого коммита от session #2, так почему он вправе еще и МЕНЯТЬ запись, перетирать её ?А почему он не вправе это делать ? Не потому ли, что кто-то не понимает уровней изоляции тр-ций и принципов конкурентного программирования ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2014, 16:36:17 |
|
||
|
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
|
|||
|---|---|---|---|
|
#18+
hvladТаблоидНо сам стейтмент от session #1 начался *ДО* этого коммита от session #2, так почему он вправе еще и МЕНЯТЬ запись, перетирать её ?А почему он не вправе это делать ?Если говорить об UPDATE (а не о select for update), то нелогично как-то выглядит: при rc rec_ ver в этой ситуации вываливается update conflict, и это - гут, так и должно быть. А при no_ rec_ver этот же update уже тихо перетирает чужое изменение. Если же говорить о SELECT for update, то он хотя и селект, но таки делается для последующего АПДЕЙТА. И если он увидел запись, которая была изменена и закоммичена после его старта, то вопить бы ему надо. Или автоматом перезапуститься, как это происходит в орацле. hvladНе потому ли, что кто-то не понимает уровней изоляции тр-ций и принципов конкурентного программирования ?Что именно я не понимаю в TIL и причём тут "принципы конкурентного программирования" ? :-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2014, 16:57:49 |
|
||
|
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
|
|||
|---|---|---|---|
|
#18+
Таблоидто нелогично как-то выглядит: при rc rec_ver в этой ситуации вываливается update conflict, и это - гут, так и должно быть. А при no_rec_ver этот же update уже тихо перетирает чужое изменение. похоже, у тебя входит в привычку намешивать все в кучу. "конфликт" вываливается при nowait. Что там кто перетирает - в wait. А? Составь таблицу - RC/Snapshot, wait/nowait, и т.д. как какой вариант реагирует на update/select_with_lock незакоммиченой записи. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2014, 17:08:05 |
|
||
|
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
|
|||
|---|---|---|---|
|
#18+
ТаблоидЕсли же говорить о SELECT for update, то он хотя и селект, но таки делается для последующего АПДЕЙТА. И если он увидел запись, которая была изменена и закоммичена после его старта, то вопить бы ему надо. RC может обновить любые чужие committed изменения. почему update это может делать, а select for update "должен вопить"??? Ведь select for update - это update, никаким другим способом "заблокировать" запись в ФБ нельзя. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2014, 17:10:33 |
|
||
|
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
|
|||
|---|---|---|---|
|
#18+
kdv"конфликт" вываливается при nowait . Что там кто перетирает - в wait. А?Йок! Конфликт в read committed вылазит только при record_version, а wait / no wait /lock timeout NN - побоку. Во, смотри: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. ЗЫ. Мне для теста WAIT - это смерти подобно, там вообще всё заткнётся. Надеюсь обойтись без него. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.03.2014, 17:34:34 |
|
||
|
|

start [/forum/topic.php?fid=40&msg=38589598&tid=1563796]: |
0ms |
get settings: |
9ms |
get forum list: |
18ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
60ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
80ms |
get tp. blocked users: |
1ms |
| others: | 240ms |
| total: | 431ms |

| 0 / 0 |
