172 похожих чатов

А в PG есть "перезапуски апдейтов"? Поток 1: update t set y

= 10 where y = 5; [не коммитит]
Поток 2:
update t set x = x+1 where y = 5;
Поток 1:
commit;

вроде как, второй поток должен (read commited по дефолту) увидеть ещё не-модифицированную строку, и встать в очередь на блокировку; но когда дождётся, то ему придётся перепроверять, верно ли до сих пор, что y = 5? или тут это как-то по-другому работает?

12 ответов

13 просмотров

Почитайте https://www.postgresql.org/docs/current/transaction-iso.html#XACT-READ-COMMITTED , там всё описано (я не знаю, что Вы имеете в виду под "перезапусками" / как это работает в Oracle, поэтому не могу точно сказать). > Это PG "умнее" и просто триггер лишний раз не запускает? Before update trigger запускается после того, как row удаётся заблокировать, вроде (и update же в любом случае выполняется однократно, откуда там два запуска?).

Ilya-Portnov Автор вопроса
Yaroslav Schekin
Почитайте https://www.postgresql.org/docs/current/...

ну вот в моём примере: * второй поток ищет строку с y = 5 * видит только ту версию, которая была до обновления (т.к. первый поток ещё не сказал commit) * видит что эта строка заблокирована * висит на блокировке * дожидается коммита в первом потоке * опа, а теперь в той строке (в новой версии) уже y = 10, значит апдейтить её не надо вот эту вторую проверку Кайт называет "перезапуском". Собственно, ваша ссылка рассказывает то же самое. UPDATE, DELETE, SELECT FOR UPDATE, and SELECT FOR SHARE commands behave the same as SELECT in terms of searching for target rows: they will only find target rows that were committed as of the command start time. However, such a target row might have already been updated (or deleted or locked) by another concurrent transaction by the time it is found. In this case, the would-be updater will wait for the first updating transaction to commit or roll back (if it is still in progress). If the first updater rolls back, then its effects are negated and the second updater can proceed with updating the originally found row. If the first updater commits, the second updater will ignore the row if the first updater deleted it, otherwise it will attempt to apply its operation to the updated version of the row. The search condition of the command (the WHERE clause) is re-evaluated to see if the updated version of the row still matches the search condition.

Ilya Portnov
ну вот в моём примере: * второй поток ищет строку...

Привет! Если ты интересуешься технологиями, я хотел бы порекомендовать тебе канал про техническую сторону разработки. Там ты найдешь много интересных видео и статей о новых технологиях, программировании и других темах. 📺🔧 Там есть много видео и статей, которые легко понять даже для новичков. 🙌 И самое крутое, что они всегда в курсе последних трендов и новинок в мире технологий. 😎💡 Так что, если ты хочешь быть в курсе всех новостей и тенденций в мире технологий, заходи на этот канал! Там тебя ждет много интересного и полезного контента. 💻📱 А вот сама ссылка, чтобы ты смог быстро найти этот канал: [ссылка]. Удачи и приятного просмотра! 😉👍

Алина Романова
Привет! Если ты интересуешься технологиями, я хоте...

> вот эту вторую проверку Кайт называет "перезапуском". Я слышал, что в Oracle эти самые "перезапуски" — это что-то совсем другое. > is re-evaluated to see if the updated version of the row still matches the search condition. И мне непонятно, почему это "перезапуск", по сути — повторно вычисляется только условие, и только для [новой версии] конкретной записи. Соответственно, ни на какие триггеры это никак не влияет.

Ilya Portnov
ну вот в моём примере: * второй поток ищет строку...

> вот эту вторую проверку Кайт называет "перезапуском". Я слышал, что в Oracle эти самые "перезапуски" — это что-то совсем другое. Edit: вот, например: https://dba.stackexchange.com/a/91398 > is re-evaluated to see if the updated version of the row still matches the search condition. И мне непонятно, почему это "перезапуск", по сути — повторно вычисляется только условие, и только для [новой версии] конкретной записи. Соответственно, ни на какие триггеры это никак не влияет.

Yaroslav Schekin
> вот эту вторую проверку Кайт называет "перезапус...

Я вот сижу и думаю -- получается, что в некоторых случаях постгрес можэт увидеть пол-транзакцыи? То есть у нас в таблицэ value = 3 и 6. Первый update обновляет все value=value+1, и идёт (так получилось) по возрастанию. Второй -- обновляет все нечётные value, делает value=-value , и идёт (так получилось) по убыванию. Первый нашёл value=3, сделал value=4. Второй нашёл value=6, пропустил его. Первый нашёл value=6, сделал value=7 Второй нашёл value=3, но обновлённый незакоммиченной транзакцыей. Завис. Первый дошёл до конца, закоммитил транзакцыю. Второй увидел, что значение value=3 удалено, пропустил его (возможно, увидел, что есть value=4, пропустил и его). Итого: с точки зрения транзакцый состояние таблицы -- сначала value=3,6 после коммита -- 4,7 По идее -- второй update должэн увидеть или первое или второе. И сделать состояние или -3,6 или 4,-7 А он видит 6 и 4, то есть половины результатов транзакцыи!

Ilya Anfimov
Я вот сижу и думаю -- получается, что в некоторых ...

Нет никакой пол транзакции, есть данные до выполнения параллельной транзакции и после ее фиксации. Аномалия неповторяющегося чтения это нормально для read commited

Ilya Anfimov
Я вот сижу и думаю -- получается, что в некоторых ...

> Итого: с точки зрения транзакцый состояние таблицы -- сначала value=3,6 после коммита -- 4,7 Ну так это всё и есть, что тут удивительного? Более того, документация приводит аналогичный пример: More complex usage can produce undesirable results in Read Committed mode. For example, consider a DELETE command operating on data that is being both added and removed from its restriction criteria by another command, e.g., assume website is a two-row table with website.hits equaling 9 and 10: BEGIN; UPDATE website SET hits = hits + 1; -- run from another session: DELETE FROM website WHERE hits = 10; COMMIT; The DELETE will have no effect even though there is a website.hits = 10 row before and after the UPDATE. This occurs because the pre-update row value 9 is skipped, and when the UPDATE completes and DELETE obtains a lock, the new row value is no longer 10 but 11, which no longer matches the criteria.

Ilya Anfimov
Я вот сижу и думаю -- получается, что в некоторых ...

> то есть половины результатов транзакцыи! Но я (наверное) понимаю, о чём Вы... да, snapshot-ы в READ COMMITTED "подтекают" (т.е. SELECT и UPDATE (или SELECT FOR UPDATE ) с теми же условиями могут видеть разные данные в рамках того же запроса (и это легко воспроизвести)) — но ничего, не соответствующего ISO SQL, тут нет. И да, в типичных реализациях RC в "блокировочниках" аномалии ещё более "волшебные" (они могут N раз "видеть" одну и ту же запись, например), кстати — и это тоже нормально (соответствует ISO SQL). Вот поэтому я всегда говорю, что для практической работы (на уровнях изоляции ниже S) с той или иной СУБД знать, что там пишет ISO SQL про уровни изоляции (опять-таки, кроме S) — бесполезно. Механизмы работы этих уровней в конкретной СУБД надо знать, и точка.

Yaroslav Schekin
> то есть половины результатов транзакцыи! Но я (...

И, видимо, чтобы этого избежать -- Оракл при блокировке перезапускает (откатывает и перезапускает) ВЕСЬ update. Что само по себе очень весело.

Похожие вопросы

Обсуждают сегодня

Anyone here suffers from unexplained aural migraines, who would be up for talking for a bit? Doesn't *have* to be aural, but I am not asking about headaches, I mean actual mi...
Martin Rys
46
подскажите пожалуйста, как мне освободить результат записанный в переменную result? в чем проблема подскажите если МОЖЕТЕ?
Михаил Helper
28
вопрос по москвину - не понимаю вот такого вопроса похоже Сколько разных всегда завершающихся функций с типом a -> a -> b -> a -> a можно реализовать? Две функции одинаково...
Fedor
11
Слушайте, ещё такая интересная задачка. Сделан аудит действий пользователей через триггеры в базе, соответственно каждый пользователь имеет свой логин и пароль в базе. Это пре...
Сергей Бычков
11
есть тут кто-то , кто только начал изучать си? если проходите курс на степике или как-то сами изучаете, пишите, может, скооперируемся?..
Eule
25
Скажите, тут нет проблемы? IMyInterface1 = interface function GetInterface2: IInterface2; ... function TMyInterface.GetInterface2: IInterface2; begin Result := TI...
Ruslan aka DUDE
18
Утра доброго. Просветите пожалуйста. Хочу сделать rest сервер на делфи. Посмотрел 3 фреймворка: dmvc, Mars, mormot. Ни в одном из них не упоминается ассинхронная обработка вхо...
Сергей Бычков
10
возможно для форматирования TimeStampZ нужен другой механизм, не?
Роман Лях (rgreat)
13
вопрос странный немного... в секции interface идёт константа const TableExt: array [0..39] of record _type: byte; _ext : string; end = ( (_type:typeDAT ...
Alexey Kulakov
5
Всем привет! Помогите разобраться с Lazarus. Переношу программу с Delphi 10.2 Tokyo на Lazarus 3.2. У меня есть строка string которая изначально имеет такое содержание (то чт...
Дмитрий Завгородний
4
Карта сайта