NOTIFY

NOTIFY — gera uma notificação

Sinopse

NOTIFY canal [ , carga ]

Descrição

O comando NOTIFY envia um evento de notificação, junto com uma cadeia de caracteres de carga útil opcional, para cada aplicação cliente que executou anteriormente o comando LISTEN canal para o nome do canal especificado no banco de dados corrente. As notificações são visíveis para todos os usuários.

O comando NOTIFY fornece um mecanismo simples de comunicação entre processos, para uma coleção de processos acessando o mesmo banco de dados do PostgreSQL. Uma cadeia de caracteres de carga útil pode ser enviada junto com a notificação, e mecanismos de nível superior para passar dados estruturados podem ser construídos usando tabelas no banco de dados para passar dados adicionais do notificador para o(s) ouvinte(s).

As informações transmitidas ao cliente por um evento de notificação incluem o nome do canal notificador, o PID do processo servidor da sessão notificadora, e a cadeia de caracteres de carga útil, que será uma cadeia de caracteres vazia se não tiver sido especificada.

Cabe ao projetista do banco de dados definir os nomes dos canais que serão utilizados em determinado banco de dados, e o que cada um significa. Normalmente, o nome do canal é o mesmo que o nome de alguma tabela no banco de dados, e o evento de notificação significa essencialmente, Mudei esta tabela, dê uma olhada nela para ver o que há de novo. Mas esta associação não é imposta pelos comandos NOTIFY e LISTEN. Por exemplo, um projetista de banco de dados pode usar vários nomes de canais diferentes para sinalizar diferentes tipos de alterações em uma única tabela. Como alternativa, a cadeia de caracteres de carga útil pode ser usada para diferenciar vários casos.

Quando o comando NOTIFY é usado para sinalizar a ocorrência de alterações em uma tabela específica, uma técnica de programação útil é colocar o comando NOTIFY em um gatilho de comando acionado por atualizações da tabela. Dessa forma, a notificação acontece automaticamente quando a tabela é alterada, e o programador da aplicação não poderá esquecer acidentalmente de fazê-lo.

O comando NOTIFY interage com as transações SQL de algumas maneiras importantes. Em primeiro lugar, se o comando NOTIFY for executado numa transação, os eventos de notificação não serão entregues até, e a menos que, a transação seja efetivada. Isto é apropriado, porque se a transação for interrompida, todos os comandos dentro dela não terão efeito, incluindo o NOTIFY. Mas pode ser desconcertante se alguém espera que os eventos de notificação sejam entregues imediatamente. Em segundo lugar, se uma sessão ouvinte receber um sinal de notificação enquanto estiver em uma transação, o evento de notificação não será entregue ao seu cliente conectado até logo após a conclusão da transação (efetivada ou interrompida). Novamente, o raciocínio é que, se a notificação foi entregue em uma transação interrompida posteriormente, seria desejável que a notificação fosse desfeita de alguma forma — mas o servidor não pode pegar de volta uma notificação após enviá-la ao cliente. Portanto, os eventos de notificação são entregues apenas entre as transações. O resultado disso é que as aplicações que usam o comando NOTIFY para sinalização em tempo real devem tentar manter suas transações curtas.

Se o mesmo nome de canal for sinalizado várias vezes com cadeias de caracteres de carga útil idênticas na mesma transação, apenas uma instância do evento de notificação será entregue aos ouvintes. Por outro lado, as notificações com cadeia de caracteres de carga útil distintas sempre serão entregues como notificações distintas. Da mesma forma, as notificações de diferentes transações nunca serão reunidas em uma única notificação. Exceto para remover instâncias posteriores de notificações duplicadas, o comando NOTIFY garante que as notificações da mesma transação sejam entregues na ordem em que foram enviadas. Também é garantido que as mensagens de diferentes transações sejam entregues na ordem em que as transações foram efetivadas.

É comum que o cliente que executa o comando NOTIFY esteja ouvindo no mesmo canal de notificação. Neste caso, ele receberá o evento de notificação, da mesma forma que todas as outras sessões ouvintes. Dependendo da lógica da aplicação, isto pode resultar em trabalho inútil, por exemplo, ler uma tabela do banco de dados para encontrar as mesmas atualizações que aquela sessão acabou de fazer. É possível evitar este trabalho extra observando se o PID (fornecido na mensagem do evento de notificação) do processo servidor da sessão notificadora é igual ao PID da própria sessão (disponível pela libpq). Quando são iguais, o evento de notificação é o retorno do próprio trabalho, podendo ser ignorado.

Parâmetros

canal

O nome do canal de notificação a ser sinalizado (qualquer identificador).

carga

A cadeia de caracteres de carga útil a ser comunicada junto com a notificação. Deve ser especificada como um literal de cadeia de caracteres simples. Na configuração padrão, deve ser menor que 8000 bytes. (Se for necessário comunicar dados binários, ou grandes quantidades de informações, é melhor colocá-los em uma tabela de banco de dados e enviar a chave do registro.)

Notas

Há uma fila contendo as notificações enviadas, mas que ainda não foram processadas por todas as sessões ouvintes. Se esta fila ficar cheia, as transações que executarem o comando NOTIFY irão falhar na efetivação. A fila é bastante grande (8 GB em uma instalação padrão), devendo ter tamanho suficiente para quase todos os casos de uso. No entanto, nenhuma limpeza poderá ocorrer se uma sessão executar o comando LISTEN e depois entrar em uma transação por um tempo muito longo. Quando a fila estiver pela metade, serão encontrados avisos no arquivo de registro de transações apontando para a sessão que está impedindo a limpeza. Neste caso, deve-se certificar de que esta sessão finalize sua transação corrente para que a limpeza possa prosseguir.

A função pg_notification_queue_usage retorna a fração da fila que está ocupada no momento por notificações pendentes. Veja Funções e operadores de informação do sistema para obter mais informações.

Uma transação que executa o comando NOTIFY não pode ser preparada para uma efetivação de duas fases.

pg_notify

Para enviar uma notificação, também pode ser usada a função pg_notify(text, text). Esta função recebe o nome do canal como o primeiro argumento, e a carga útil como o segundo. Esta função é muito mais fácil de usar do que o comando NOTIFY, quando é necessário trabalhar com nomes de canais e cargas úteis não constantes.

Exemplos

Configurar e executar uma sequência de ouvinte/notificação no psql:

LISTEN virtual;
NOTIFY virtual;
Notificação assíncrona "virtual" ↵
    recebida do processo servidor com PID 8448.
NOTIFY virtual, 'Esta é a carga útil';
Notificação assíncrona "virtual" ↵
    com carga útil "Esta é a carga útil" ↵
    recebida do processo servidor com PID 8448.

LISTEN foo;
SELECT pg_notify('fo' || 'o', 'pay' || 'load');
Notificação assíncrona "foo" ↵
    com carga útil "payload" ↵
    recebida do processo servidor com PID 14728.

Conformidade

Não existe o comando NOTIFY no padrão SQL.

Veja também

LISTEN, UNLISTEN, max_notify_queue_pages