De acordo com os documentos:
CONCORRENTEMENTE Atualize a visualização materializada sem bloquear seleções simultâneas na visualização materializada. (...)
... OUTROS CONTEÚDOS ...
Mesmo com esta opção, apenas um REFRESH de cada vez pode ser executado em qualquer visualização materializada .
Eu tinha uma função que verificava o tempo da última atualização para uma MATERIALIZED VIEW e, se tivessem passado mais de 60 segundos, seria para atualizá-la.
No entanto, o que aconteceria se eu tentasse atualizar uma visão materializada de dois processos separados ao mesmo tempo? eles enfileirariam ou gerariam um erro?
Existe uma maneira de detectar quando uma MATERIALIZED VIEW está sendo atualizada e, portanto, evitar tocá-la?
Atualmente, recorri a preencher um registro de tabela antes de atualizar (definir refreshing
como true
) e, em seguida, defini-lo para false
quando o processo for concluído.
EXECUTE 'INSERT INTO refresh_status (last_update, refreshing)
VALUES (clock_timestamp(), true) RETURNING id') INTO refresh_id;
EXECUTE 'REFRESH MATERIALIZED VIEW CONCURRENTLY my_mat_view';
EXECUTE 'UPDATE refresh_status SET refreshing=false WHERE id=$1' USING refresh_id;
Então, sempre que chamo esse procedimento, verifico o mais recente last_update
e seu refreshing
valor. Se refreshing
for true, não tente atualizar a visualização materializada.
EXECUTE 'SELECT
extract(epoch FROM now() - (last_update))::integer,
refreshing
FROM refresh_status
ORDER BY last_update DESC
LIMIT 1' INTO update_seconds_ago, refreshing;
IF(updated_seconds_ago > 60 AND refreshing = FALSE) THEN
-- the refresh block above
END IF;
No entanto, não tenho certeza se o sinalizador de atualização está sendo atualizado de forma síncrona (quer dizer, ele realmente espera que a atualização seja realmente concluída)
Essa abordagem é racional ou estou perdendo alguma coisa aqui?