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

Подскажите пожалуйста почему одна из сериализационных транзакций не фейлит: Первая транзакция: SELECT

* FROM users WHERE email = ’test@test.com’
(тут пауза 5 сек)
INSERT INTO users (email) VALUES ('test@test.com')

Вторая транзакция:
INSERT INTO users (email) VALUES ('test@test.com')

Первая транзакция запускается сразу. Вторая в промежутке между запросами в первой транзакции

По идее результат второй транзакции, влияет на то, что возвращает первый запрос в первой транзакции. Но фейла не происходит.

Почему так?

Если во вторую транзакцию добавить select (такой же как у первой), то фейл происходит.

30 ответов

9 просмотров

Как уровень изоляцыи выставляете?

Alexander
serializable

Я спросил -- как.

Alexander- Автор вопроса

Фигня, впрочем. Действительно, почему должна. Добавились две строчки, сначала из первой транзакцыи, затем из второй. Отличная сериализацыя.

Alexander- Автор вопроса
Ilya Anfimov
Фигня, впрочем. Действительно, почему должна. Доба...

Ну пока выполянется первая транзакция, и приходит вторая, которвя по идее влияет на то, что мог бы вернуть select в первой

Alexander
Ну пока выполянется первая транзакция, и приходит ...

Так вторая выполняется после первой. Ну, в рамках сериализацыи.

Alexander- Автор вопроса
Ilya Anfimov
Так вторая выполняется после первой. Ну, в рамках ...

А почему добавления select заставляет фейлить?

Alexander
А почему добавления select заставляет фейлить?

Потому, что после этого ужэ не скажэшь что "вторая выполнилась после первой". Если бы это было так -- во втором селекте был бы этот результат, а его нет.

Alexander- Автор вопроса
Ilya Anfimov
Так вторая выполняется после первой. Ну, в рамках ...

Я вот тут не понимаю. У меня вторая транзакции накладывается на первую и влияет на то как бы отработала первая

Alexander
Я вот тут не понимаю. У меня вторая транзакции нак...

Вторая транзакцыя не влияет на первую потому, что считается, что она отработала после первой.

Alexander- Автор вопроса
Ilya Anfimov
Вторая транзакцыя не влияет на первую потому, что ...

Так а почему тогда я добавляю select фэйл происходит, если вторая считается отработавшей после первой?

Alexander
Так а почему тогда я добавляю select фэйл происход...

Потому, что она не получила результатов первой транзакцыи. А если бы отработала после -- то должна была получить.

Alexander- Автор вопроса
Ilya Anfimov
Потому, что она не получила результатов первой тра...

Тогда в такой ситуации должно зафейлить? Но не фейлит Первая транзакция: BEGIN SET TRANSACTION ISOLATION LEVEL SERIALIZABLE INSERT INTO users (email) VALUES ('test@test.com') — в этот момент запускается вторая — COMMIT Вторая транзакция: BEGIN SET TRANSACTION ISOLATION LEVEL SERIALIZABLE SELECT * FROM users WHERE email = 'test@test.com’ COMMIT

Alexander- Автор вопроса
Alexander
Тогда в такой ситуации должно зафейлить? Но не фей...

Пробовал делать коммит второй до заврешения первой и после завершения. Не фейлит

Alexander
Тогда в такой ситуации должно зафейлить? Но не фей...

Нет, почему бы? Вторая считается отработала до первой, всё в порядке.

Alexander- Автор вопроса
Ilya Anfimov
Нет, почему бы? Вторая считается отработала до пер...

А если коммит делать после коммита первой?

Alexander- Автор вопроса
Ilya Anfimov
Да без разницы в данном случае.

Почему? Не понимаю механизм

Alexander- Автор вопроса
Ilya Anfimov
Почему что?

Почему без разницы?

Alexander
Почему без разницы?

Потому, что это сработает.

Alexander- Автор вопроса
Alexander
Почему?

Почему что?

> По идее результат второй транзакции, влияет на то, что возвращает первый запрос в первой транзакции. > Но фейла не происходит. > Почему так? Потому что всё это не имеет отношения к фундаментальному принципу / требованию serializable, вот и всё. В PostgreSQL apparent transaction order может не совпадать ни с последовательностью запуска транзакций, ни с последовательностью их завершения. И уж тем более он не обязан иметь хоть какое-то отношение к реальному времени.

Yaroslav Schekin
> По идее результат второй транзакции, влияет на т...

>apparent transaction order может не совпадать ни с последовательностью запуска транзакций, ни с последовательностью их завершения. Интересно, кстати, а то, что он будет совпадать с календарным если время старта и завершэния полностью разделено (т.е. вторая началась после того, как завершылась первая) -- разработчики как-то пытаются гарнтировать -- или это просто пока вот так получается что совпадает из-за особенностей реализацыи?

Ilya Anfimov
>apparent transaction order может не совпадать ни ...

Это, вполне возможно, вопрос определения. Первая попавшаяся ссылка: https://aphyr.com/posts/313-strong-consistency-models "In a serializable database, a transaction like read x is always allowed to execute at time 0, when x had not yet been initialized. Or it might be delayed infinitely far into the future! The transaction write 2 to x could execute right now, or it could be delayed until the end of time, never appearing to occur." ну и т.д., там есть примеры. В ISO SQL требования совпадения порядка в случае "вторая началась после того, как завершылась первая" тоже нет, насколько я помню. Но "обычные" (не распределённые) СУБД этот принцип всегда соблюдают, насколько я знаю.

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

>Другими словами в данном случае можно придумать сериализованный порядок Кстати, что-то подумал поутру -- возможно у вас тупик по поводу того, как postgresql это делает. Возможно, если бы я не знал как -- тожэ был бы в шоке, что за квантовая запутанность. На самом деле да, он запоминает критэрии поиска. И если потом какое-то обновление начинает обновлять что-то, подходящее под эти критэрии -- то начинает откатывать, какую откатывать -- выбирает по обстоятельствам. Это кроме правила создания снапшота для repeatable read -- что видны только данные (и все данные), у которых номер транзакцыи их записавшэй меньшэ либо равен текущей.

Aleksey Stavrov
В примере, как у Вас, если вначале выполнится перв...

> Другими словами в данном случае можно придумать сериализованный порядок, Я бы дажэ сказал, не "можно", а "получилось". В соответствии с упрощёнными правилами "придумывания", которые реализованы в postgres и для которых когда-то кто-то доказал (в достаточной степени) их корректность.

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

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

я не магистр хаскеля, но разве не может лейзи тип конвертнуться в не-лейзи запросив вычисление содержимого прям при инициализации?
deadgnom32 λ madao
100
короче сгенерила мне эта штука код на ассемблере: struc string val { common local .value dq .value .value: if ~val eq db val end if db 0 } fo...
Vi Chapmann Chapmann
12
Всем привет! Массив вводится с клавиатуры, кол-во элементов неизвестно, поэтому я указал arr db 100 dup(?) С нахождением максимума проблем нет, а вот минимум почему-то всегд...
En Vind Av Sorg
11
кто шарит: mattermost отслеживает что ты на пк запускаешь?
Valentin
13
Помогите, пожалуйста, делаю программу для для подсчёта корней квадратного уравнения, знаю, что есть куча недочётов, недоработок, но основная проблема в том, что почему-то при ...
NYC
13
#include <stdio.h> int main(void) { int n; scanf("%d", &n); int digits1[n] = {0}; int digits2[n] = {0}; я не могу таким образом заранее массив нулями заполнить?
Linus
12
в сях есть множество как в питоне? для удаление дубликатов
Linus
25
читать файл максимально быстро? странный вопрос))
zamtmn
53
я про форму записи. смысл указывать что 8 байтный регистр 8 байт?
Aiwan \ (•◡•) / _bot
10
Вроде бы вопрос уже заезжанный, но тем не менее У меня есть функция menu() которая выводит набор возможных действий, а затем спрашивает у пользователя что он хотел бы сделать....
David Golovatin
5
Карта сайта