Конкурентный доступ к кортежу в PostgreSQL

Есть таблица с счетом, на которую наваливается сразу много запросов, которые списывают с него средства:

create table account
(
    id BIGSERIAL PRIMARY KEY,
    volume BIGINT NOT NULL DEFAULT 0
);

update account
set volume = volume - 10
where id = 1 and volume > 10;

Как можно средствами SQL гарантировать что утечки данных при update не будет.

Как я понимаю, если повышать уровень изоляции, то это только усугубит проблему, так как актуальность данных при чтении еще уменьшится. Но конкурентный доступ нужно обеспечить. Что для этого нужно сделать и почему? Спасибо.


Ответы (1 шт):

Автор решения: Мелкий

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

Запросы

update account
set volume = volume - 10
where id = 1 and volume > 10;

Замечательно сериализуются самой СУБД на ожидании row-level блокировки строки. postgresql выполняет update всегда над самой актуальной версией подходящей по условию строки.


Проблема у вас будет, если вы попытаетесь расчёт нового volume вынести на приложение:

begin;
select volume from account where id = ?;
-- некоторая логика на приложении
update account set volume = ? where id = ?;
commit;

Здесь race condition есть.

→ Ссылка