@aarifkhamdi

Есть ли разница между выражением и транзакцией?

Если два запроса (чтение и обновление) происходят внутри одной транзакции READ COMMITED, то, понятное дело, мы не можем быть уверены, что обновление обязательно произойдет. Данные могли измениться в другой транзакции.

А как насчет одного выражения? Судя из документации внутри выражения видны одни и те же строки. Можем ли мы быть уверены, что в следующей конструкции обновление обязательно произойдет (считаем что SELECT вернул какие-то данные)?

WITH t (
    SELECT id
    FROM test
    WHERE (id = 1) AND (value = 2)
    RETURNING id
)
UPDATE test
SET value = 3
FROM t
WHERE
        (test.id = t.id)
    AND (t.value = t.value)


Дополнительно: есть ли какой-то способ это проверить, чтобы не задавать такие вопросы. Есть ли какой-нибудь инструмент, чтобы приостановить запрос и посмотреть что будет, если произойдет X?
  • Вопрос задан
  • 46 просмотров
Решения вопроса 1
Melkij
@Melkij
PostgreSQL DBA
Можем ли мы быть уверены, что в следующей конструкции обновление обязательно произойдет (считаем что SELECT вернул какие-то данные)?

Нет, не можем.
Два конкурентных запроса могут увидеть одни и те же версии строк в cte (не пересекутся на читающих блокировках даже с конкурентными писателями т.к. mvcc) и затем пойдут обновлять одни и те же строки. На блокировках обновления строк их транзакции и сериализуются. Кстати, можно и deadlock словить если строк к обновлению будет несколько и они вернутся из запроса в разном порядке.

приостановить запрос и посмотреть что будет, если произойдет X?

gdb может приостановить всё что угодно. Правда далее уже интересный момент что надо найти куда именно break point ставить.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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