Según los documentos:
CONCURRENTEMENTE Actualizar la vista materializada sin bloquear selecciones concurrentes en la vista materializada. (...)
... OTROS CONTENIDOS ...
Incluso con esta opción, solo un REFRESH a la vez puede ejecutarse contra cualquier vista materializada .
Yo tenía una función que comprueba el último tiempo de actualización de una vista materializada y, si habían pasado más de 60 segundos, sería para actualizarlo.
Sin embargo, ¿qué sucedería si trato de actualizar una vista materializada de dos procesos separados al mismo tiempo? ¿harían cola o generarían un error?
¿Hay alguna forma de detectar cuándo se actualiza una VISTA MATERIALIZADA y, por lo tanto, evitar tocarla?
Actualmente, he recurrido a rellenar un registro de tabla antes de actualizar (establecer refreshing
en true
) y luego configurarlo false
cuando el proceso haya finalizado.
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;
Luego, cada vez que llamo a este procedimiento, verifico el más reciente last_update
y su refreshing
valor. Si refreshing
es cierto, no intente actualizar la vista 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;
Sin embargo, no estoy seguro de que el indicador de actualización se actualice sincrónicamente (es decir, realmente espera a que la actualización se complete)
¿Es este enfoque racional o me falta algo aquí?