powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
38 сообщений из 38, показаны все 2 страниц
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38588855
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вопросик тут вспых.

При апдейте, натыкающемся на закоммиченную новую версию записи, транзакция получит по лбу:
Код: plaintext
1.
-update conflicts with concurrent update
-concurrent transaction number is 20034

Допустим, в таблице `t` изначально было вот это:
Код: plaintext
1.
2.
3.
4.
ID          F01
== ============
 1          100
 2          200
 3          300

Если теперь сделать вот так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
 session #1 
commit; set transaction  read committed record_version lock timeout 20 ;
 
session #2 
update t set f01=-f01 where id=2;

 session #1 
select * from t where id=2  for update with lock ; -- тут она будет висеть 20 сек. Иду теперь в session #2...

 session #2 
-- ... и быстро ввожу:
commit;

- то получаю в session #1
Код: plaintext
1.
2.
 ID          F01
=== ============
  2         -200

То же самое будет, если session #1 стартанёт транзакцию как NO record_version.
Но при старте этой сессией вот так:
Код: plaintext
set transaction  snapshot  lock timeout 20;
- она при этом сценарии получит по лбу тем же "update conflicts with concurrent update", как если бы стартовала сам апдейт, а не select for update with lock.

Так вот, вопрос: не было бы логичнее выдавать эту же ошибку и при старте в режиме read committed ? Ведь select ... for update with lock - он же не с будуна введён, а для апдейта .
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38588876
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидВопросик тут вспых.А давай без вспыхов, сам объясни - почему это правильно
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38588884
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоид,

а в чем вопрос? в том, что снапшоту чужие изменения видеть нельзя пожизненно, а RC - можно? Или вопрос в другом?
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38588959
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdv,

нет, он просто не понимает, зачем WITH LOCK в RC тр-ции работает в режиме NO_REC_VER
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38589011
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvladТаблоидВопросик тут вспых.А давай без вспыхов, сам объясни - почему это правильноЭто формально правильно, т.к. select стартовал RC и, когда запись стала ему доступной (при коммите другой трн), то он должен видеть закоммиченные изменения. Вот он и видит f01 = -200.
Однако, select этот (session #1) дёргает запись для изменения .
Когда он её нашёл, в ней было еще id = 2, f01= + 200 - она её именно такой видел.
Когда же он её получил в распоряжение, то там оказалось f01= - 200.

Если он теперь будет перетирать значение f01 чем-то другим (вместо выброса ошибки), то не похоже ли это на синдром LOST UPDATE ?
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38589014
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitrон просто не понимает, зачем WITH LOCK в RC тр-ции работает в режиме NO_REC_VERДа, я не понял этого, т.к. начал эксперимент с rc rec_ver.
Ну так объясни мне, плз: почему snapshot, натыкаясь на обновлённую запись, НЕ позволяет произойти lost update и вываливает ошибку (что есть гут, КМК), а RC - запросто.
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38589082
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоид,

снапшот в принципе не может перечитать измененные конкурентом данные, поэтому ошибка там неизбежна. В RC это возможно, в текущей реализации это позволяет режим NO_REC_VER. Я не понимаю, зачем ты приплетаешь тут lost update, ибо ситуация полностью аналогична как если бы наш селект+апдейт начал выполняться после коммита конкурента, а не до. Точно также имеем перезапись чужих изменений своими. Тебя это не беспокоит? Не хочешь поговорить об этом?
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38589085
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WITH LOCK в первую очередь предназначен для сериализации доступа к общему ресурсу. Если он это сможет обеспечивать с минимумом конфликтов - тем лучше. Но Таблоиду почему-то принципы (читай: теория) вдруг стали важнее практики.
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38589185
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидКогда он её нашёл, в ней было еще id = 2, f01= + 200 - она её именно такой видел.Нет, он её такой не видел. Он увидел, что есть незакомиченные изменения и стал ждать коммита. И только потом прочитал запись.
Дальше всё как обычно - RC имеет право видеть чужие изменения, сделанные после своего старта, а snapshot - не имеет такой возможности.
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38589343
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38589360
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitrWITH LOCK в первую очередь предназначен для сериализации доступа к общему ресурсу. Если он это сможет обеспечивать с минимумом конфликтов - тем лучше. Но Таблоиду почему-то принципы (читай: теория) вдруг стали важнее практики.Во-во! Именно на сериализации доступа я и получил гемор.
Если есть документ, который надо перевести из статуса "Открыт" в статус "Закрыт", и к нему ломятся два и более аттача, то после успешного выполнения select for update в каждом аттаче надо еще раз проеверять содержимое поля "Статус": а не закрыт ли он уже ("только что") ? Ибо в селект этот выдаст строку в новом виде (с новым значением поля "Статус" и всех прочих) - тихо, без всякой ругани.
Остановился пока на дебильном
Код: sql
1.
update doc_list set set id = id where status = <open> order by rand() rows 1 returning id into :selected_doc_id;

- выполнение его в RC обязательно вывалит ошибку, если было ожидание и конкурент успел обновить этот документ.
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38589363
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvladДальше всё как обычно - RC имеет право видеть чужие изменения, сделанные после своего старта, а snapshot - не имеет такой возможности. Видеть - да. А менять ?
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38589559
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидЕсли начал выполняться некий "долгий стейтмент" в read committed, а затем он дошел до залоченной записи и застрял на ней, то это значит, что сначала он УВИДЕЛ её как подходящую под where-условиеНе надо фантазировать. Сначала читается и анализируется заголовок записи. Сама запись читается позже.

Остальной бред я даже не читал
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38589598
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоид это самый натуральный lost update.
lost update - нормальная ситуация для rc.
tr1. select
tr2. select
tr1 update
tr1 commit
tr2 update - проходит на ура.

а свой select for update with lock можешь заменить на простой update set a=a ...
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38589634
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvladСама запись читается позже.Хорошо: session #1 увидел заголовок. При no rec_version проверил, залочена ли она конкурентом. Оказалось - да, залочена, так что session #1 застрял на ней.
Дальше session #2 закоммитил изменения, и session #1 тут же получил запись.
ВИДЕТЬ запись в изменённом виде session #1, безусловно, ДОЛЖЕН, ведь это RC.
Но сам стейтмент от session #1 начался *ДО* этого коммита от session #2, так почему он вправе еще и МЕНЯТЬ запись, перетирать её ?
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38589655
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdvТаблоид это самый натуральный lost update.
lost update - нормальная ситуация для rc.
Код: plaintext
1.
2.
3.
4.
tr1. select
tr2. select
 tr1 update 
tr1 commit
 tr2 update  
- проходит на ура.Это и так понятно! Потому что у тебя время начала tr1 update и его коммита НЕ пересекается с временем начала tr2 update + tr2 commit.
Я же говорю про случай, когда:
Код: plaintext
1.
2.
3.
4.
tr1. select
tr2. select
 tr1 update 
 tr2 update 
tr1 commit
И теперь в tr2 будет:
1) ОБЛОМ при rc REC_version и
2) ТИХОЕ ПЕРЕТИРАНИЕ при rc NO_rec_version
kdvа свой select for update with lock можешь заменить на простой update set a=a ...Дык!..
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38589668
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидКогда селект / апдейт стартует после чужого коммита - какие проблемы, всё ОК. Но когда он стартует *до*, молотит там что-то, а затем доходит до чужой залоченной записи и, дожидаясь её высвобождения, ТИХО перетирает
а какая половая разница (с точки зрения lost update в случае RC транзакции) между двумя этими случаями? Почему lost update в первом случае ты считаешь нормальным, но бесишься во втором?
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38589677
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидИменно на сериализации доступа я и получил гемор.
Если есть документ, который надо перевести из статуса "Открыт" в статус "Закрыт", и к нему ломятся два и более аттача, то после успешного выполнения select for update в каждом аттаче надо еще раз проверять содержимое поля "Статус": а не закрыт ли он уже ("только что") ?
ты закрываешь пачку документов разом, что-ли? А нафига тут вообще что-то лочить?
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38589696
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitrТаблоидКогда селект / апдейт стартует после чужого коммита - какие проблемы, всё ОК. Но когда он стартует *до*, молотит там что-то, а затем доходит до чужой залоченной записи и, дожидаясь её высвобождения, ТИХО перетираета какая половая разница (с точки зрения lost update в случае RC транзакции) между двумя этими случаями? Почему lost update в первом случае ты считаешь нормальным, но бесишься во втором?Да как это ?!
Если коннект-2 закоммитил запись и *после* этого любой стартующий стейтмент коннекта-1 будет обламываться - это как тогда работать-то ?!

Это всё шутка юмора, конечно. В текстах стандарта 2003 и 2006 я не вижу упоминания про т.н. "феномен-4" (P4), про который говорится тут . Но раз наступление этого "P4" блокируется при изменениях в rc rec_ver, то почему это же не сделано в rc NO_rec_ver ?
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38589701
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitrТаблоидИменно на сериализации доступа я и получил гемор.
Если есть документ, который надо перевести из статуса "Открыт" в статус "Закрыт", и к нему ломятся два и более аттача, то после успешного выполнения select for update в каждом аттаче надо еще раз проверять содержимое поля "Статус": а не закрыт ли он уже ("только что") ?
ты закрываешь пачку документов разом, что-ли? А нафига тут вообще что-то лочить?Нет, наоборот. Документы будут генериться 300 аттачами, они при этом будут в состоянии "НЕ закрыт".
Также будет создано 30 аттачей, каждый из которых будет выбирать случайный (или "не очень") документ для закрытия. Столкновение лбами кого-то из этих 30 аттачей неминуемо.
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38589714
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидНо сам стейтмент от session #1 начался *ДО* этого коммита от session #2, так почему он вправе еще и МЕНЯТЬ запись, перетирать её ?А почему он не вправе это делать ?
Не потому ли, что кто-то не понимает уровней изоляции тр-ций и принципов конкурентного программирования ?
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38589745
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvladТаблоидНо сам стейтмент от session #1 начался *ДО* этого коммита от session #2, так почему он вправе еще и МЕНЯТЬ запись, перетирать её ?А почему он не вправе это делать ?Если говорить об UPDATE (а не о select for update), то нелогично как-то выглядит: при rc rec_ ver в этой ситуации вываливается update conflict, и это - гут, так и должно быть.
А при no_ rec_ver этот же update уже тихо перетирает чужое изменение.
Если же говорить о SELECT for update, то он хотя и селект, но таки делается для последующего АПДЕЙТА. И если он увидел запись, которая была изменена и закоммичена после его старта, то вопить бы ему надо. Или автоматом перезапуститься, как это происходит в орацле.

hvladНе потому ли, что кто-то не понимает уровней изоляции тр-ций и принципов конкурентного программирования ?Что именно я не понимаю в TIL и причём тут "принципы конкурентного программирования" ? :-)
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38589765
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоидто нелогично как-то выглядит: при rc rec_ver в этой ситуации вываливается update conflict, и это - гут, так и должно быть.
А при no_rec_ver этот же update уже тихо перетирает чужое изменение.
похоже, у тебя входит в привычку намешивать все в кучу.
"конфликт" вываливается при nowait. Что там кто перетирает - в wait. А?
Составь таблицу - RC/Snapshot, wait/nowait, и т.д. как какой вариант реагирует на update/select_with_lock незакоммиченой записи.
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38589770
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидЕсли же говорить о SELECT for update, то он хотя и селект, но таки делается для последующего АПДЕЙТА. И если он увидел запись, которая была изменена и закоммичена после его старта, то вопить бы ему надо.
RC может обновить любые чужие committed изменения. почему update это может делать, а select for update "должен вопить"??? Ведь select for update - это update, никаким другим способом "заблокировать" запись в ФБ нельзя.
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38589801
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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.
 session #1 
SQL> commit; set transaction read committed record_version WAIT;

 session #2 
SQL> select * from t;

          ID          F01
============ ============
           1          100
           2          200
           3          300
           4          400
           5          500

SQL> update t set f01=-id*1000 where id in(3,4);

 session #1 
SQL> update t set f01=id;
-- тут будет неизбывный затык, пока session #2 не сделает commit/rollback

 session #2 
SQL> commit;

 session #1 
Statement failed, SQLSTATE = 40001
deadlock
-update conflicts with concurrent update
-concurrent transaction number is 2936
То же самое будет при старте rc rec_ver с no wait, а также с lock timeout NN.

ЗЫ. Мне для теста WAIT - это смерти подобно, там вообще всё заткнётся. Надеюсь обойтись без него.
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38589816
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидhvladНе потому ли, что кто-то не понимает уровней изоляции тр-ций и принципов конкурентного программирования ?Что именно я не понимаю в TILВот эта фраза тебя выдаёт:
ТаблоидНо сам стейтмент от session #1 начался *ДО* этого коммита от session #2, так почему он вправе еще и МЕНЯТЬ запись, перетирать её ?это может спросить только тот, кто не понимает, что такое изоляция и как она меняется с уровнем
Таблоидпричём тут "принципы конкурентного программирования" ?Али у тебя нет конкурирующих процессов ?

PS сначала я просто плакалЬ, сейчас начну рыдать
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38589817
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоид,

ну так no_rec_version - нельзя читать старую версию , пока для нее существует не-коммиттед-версия.
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38589818
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdvВедь select for update - это update , никаким другим способом "заблокировать" запись в ФБ нельзя.Это НЕ апдейт, а только блокировка для последующего апдейта. Если селект включал в себя не только "id = :some_PK_value", но еще и доп. условие на то поле, что мы собираемся менять, то при изменении коннектом-конкурентом этого поля запись НЕ будет найдена.
Если же селект был просто с "where id = :....", то запись после получения надо заново перечитать, т.к. поле может запросто быть уже с другим значением.
В обоих случаях - лишний код. Мну кажется, что логичнее было бы выбрасывать ошибку при этом, как при апдейте.
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38589821
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvladPS сначала я просто плакалЬ, сейчас начну рыдатьЛадно. Я понял, что объяснений не будет.
Пойду рыдать дальше над update t set id=id where id = :my_selected_id :-)
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38589826
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидЯ понял, что объяснений не будет.а) я таки надеюсь на то, что ты сам поймёшь, тем более что вся информация тут уже озвучена - осталось её прочитать
б) я физически не в состоянии объяснять каждый твой "вспых", особенно в моменты обострений
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38589841
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидЭто НЕ апдейт
Это и ЕСТЬ апдейт, только без срабатывания триггеров.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38589847
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

насколько я понял, Таблоид и хочет, чтобы это был НЕ апдейт, а "блокировка".
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38589904
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdvнасколько я понял, Таблоид и хочет, чтобы это был НЕ апдейт, а "блокировка".Не, я хотел, чтобы select for update with lock вываливал ошибку 'update conflict', если после того, как он дождётся нужной записи, окажется, что в ней изменено какое-то поле (из тех, что НЕ присутствуют во where-предикате этого селекта, разумеется; иначе он её вообще не увидит :)).
То есть, чтобы он вёл себя строго так же, как update при rc rec_ver.
Но теперь понимаю, что этого нельзя сделать.

Впрочем, это и к лучшему. Конструкция вида
Код: sql
1.
2.
update doc_list h set h.id = h.id where ... order by rand() rows 1 returning f01, f02, ...  into v01, v02, ...;
if (row_count = 0) then exception ex_no_doc_found_for_handling;

- вполне себе подойдёт.
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38590084
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоидkdvнасколько я понял, Таблоид и хочет, чтобы это был НЕ апдейт, а "блокировка".Не, я хотел, чтобы select for update with lock вываливал ошибку 'update conflict', если после того, как он дождётся нужной записи, окажется, что в ней изменено какое-то поле (из тех, что НЕ присутствуют во where-предикате этого селекта, разумеется; иначе он её вообще не увидит :)).
То есть, чтобы он вёл себя строго так же, как update при rc rec_ver.
Но теперь понимаю, что этого нельзя сделать.

Впрочем, это и к лучшему. Конструкция вида
Код: sql
1.
2.
update doc_list h set h.id = h.id where ... order by rand() rows 1 returning f01, f02, ...  into v01, v02, ...;
if (row_count = 0) then exception ex_no_doc_found_for_handling;

- вполне себе подойдёт.
Долго медитировал над этим :)
Имхо нужна функция, которая бы возвращала номер транзакции для записи (в режиме грязного чтения, т.к. для закоммиченых данных у записи уже есть поле rdb$record_version).
Вот пример:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
for 
  select id, rdb$record_version, ... 
  from doc_list 
  where ... and 
  (get_record_transaction(rdb$db_key) = rdb$record_version)  // пропускаем залоченое другими транзакциями
  rows 300
  into :id, :recver
do
begin
  update doc_list set id = id where (id = :id) and
    (rdb$record_version = :recver) and                                     // не было закомиченных изменений
    (get_record_transaction(rdb$db_key) = rdb$record_version);    // запись не залочена другой транзакцией
  if (row_count = 1)   // успешный лок
  begin
    ...
    update doc_list set ... where (id = :id);
  end;
end;



И небольшое отвлечение:

Ещё можно было бы простым запросом типа
Код: sql
1.
select Id, ... from T where rdb$record_version <> get_record_transaction(rdb$db_key)

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

И уже сейчас в тройке можно видеть кто последний менял запись, если вести логи коннектов и транзакций (на db-триггерах) :)
Плохо только что после B/R это ломается...
Может всё-таки возможно при B/R не обнулять счётчик транзакций и счётчик коннектов? И чтобы поле rdb$record_version переживало B/R?

Просто мысли :)
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38590089
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоид> Впрочем, это и к лучшему. Конструкция вида
Таблоид> update doc_list h set h.id = h.id where ... order by rand()
Таблоид> - вполне себе подойдёт.

Ты всерьёз собираешься писать такое в продакшен?

P.S. Ещё начав читать предыдущий пост, я понял, что кончится
"таблицами мониторинга". Но вот что он дойдёт до счётчиков
транзакций и счётчиков коннектов с бэкап-ресторами - это даже
предположить было сложно.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38590428
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов РустамТаблоид> Впрочем, это и к лучшему. Конструкция вида
Таблоид> update doc_list h set h.id = h.id where ... order by rand()
Таблоид> - вполне себе подойдёт.

Ты всерьёз собираешься писать такое в продакшен?Не, ты чё! :-)
Это же только для теста, да там после первичных проверок будет по-другому.
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38590431
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов РустамНо вот что он дойдёт до счётчиков
транзакций и счётчиков коннектов с бэкап-ресторами - это даже
предположить было сложно.
Это ты пытаешься упрекнуть в чём? :)
...
Рейтинг: 0 / 0
RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
    #38591815
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидНе, я хотел, чтобы select for update with lock вываливал ошибку 'update conflict', если после того, как он дождётся нужной записи, окажется, что в ней изменено какое-то поле (из тех, что НЕ присутствуют во where-предикате этого селекта, разумеется; иначе он её вообще не увидит :)).Вот тут ты снова заблуждаешься.
Предикаты проверяются после того , как запись прочитана (было бы странно, если бы это было не так).
"Блокировка" накладывается до того , как запись прочитана.
Поэтому никак и никогда не может быть "что в ней изменено какое-то поле" - поля читаются у уже "заблокированной" записи.
...
Рейтинг: 0 / 0
38 сообщений из 38, показаны все 2 страниц
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / RC: select for UPDATE with lock *не* выдаёт "update confl" при изменении записи другой трн
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]