Criei uma procedure no Postgres que irá criar uma tabela com o conteúdo de outras três tabelas (SELECT com JOINS). Em seguida a tabela resultante será alterada adicionando duas colunas que não existiam antes e finalmente dentro do mesmo procedimento criei 3 triggers que serão aplicados nessas três tabelas então sempre que uma nova escrita acontecer em qualquer uma delas, a mesma entidade será gravada na nova tabela
Eu sei que o procedimento em si é atômico e transacional em seu próprio escopo, mas o procedimento não tem como saber nada sobre as três tabelas. Receio que no tempo entre a criação da nova tabela e a criação dos gatilhos, algumas gravações nas tabelas existentes possam ocorrer, dessincronizando assim a nova tabela, que não registrará essas gravações. Isso não pode acontecer.
Meu procedimento de criação de tabela/criação de gatilho é assim:
CREATE OR REPLACE PROCEDURE myschema.table_creation()
LANGUAGE plpgsql
AS $procedure$
begin
create table newtable as
SELECT * FROM myschema.session a NATURAL JOIN (SELECT * FROM myschema.message b NATURAL left JOIN myschema.data) as d;
ALTER TABLE myschema.newtable ADD created_at timestamp;
ALTER TABLE myschema.newtable ADD source text;
CREATE TRIGGER mytrigger
after INSERT
ON myschema.session
FOR EACH ROW
EXECUTE PROCEDURE myschema.trigger_proc();
CREATE TRIGGER mytrigger
after INSERT
ON myschema.messages
FOR EACH ROW
EXECUTE PROCEDURE myschema.trigger_proc();
CREATE TRIGGER mytrigger
after INSERT
ON myschema.data
FOR EACH ROW
EXECUTE PROCEDURE myschema.trigger_proc();
end;
$procedure$
;
Como posso bloquear as gravações nas tabelas existentes para adiá-las até que todo o procedimento table_creation seja concluído? Caso contrário eu teria uma condição de corrida e algumas entidades seriam perdidas na nova tabela. não acho que meu procedimento em seu estado atual tenha qualquer proteção contra gravações
Você pode iniciar seu procedimento com
Isso bloqueará todas as modificações simultâneas de dados.
Não há problema em bloquear uma tabela para uma atividade única como essa, mas você deve evitar realizar bloqueios de tabela explícitos de alto nível regularmente, porque eles interrompem o processamento de autovacuum.