2011-03-02 41 views
14

He estado jugando con el sistema de notificación de PostgreSQL y no puedo por la vida de mi figura por qué pg_notify (texto, texto) nunca funciona. Esta función no está demasiado documentada y no puedo encontrar muchos ejemplos de su uso en la naturaleza, así que pensé que a nadie le importaría que preguntara aquí.ESCUCHAR/NOTIFICAR utilizando pg_notify (texto, texto) en PostgreSQL

Ejecución de los trabajos siguientes exactamente como se esperaba:

LISTEN my_channel; 

NOTIFY my_channel, 'my message text'; 

Uso de la función pg_notify() Sin embargo devuelve un valor nulo y sin notificación alguna vez se ha enviado. No se da error tampoco. Un ejemplo de la utilización es:

SELECT pg_notify('my_channel', 'my message text'); 

que podía usar el NOTIFICAR función sin embargo, mi objetivo es simplificar la notificación en una consulta de este modo:

select pg_notify(get_player_error_channel(username)::TEXT, 'test'::TEXT) 
    from player; 

supongo que debo estar perdiendo algo ridículo, pero No he tenido suerte descubriendo el motivo de esto. La página sobre NOTIFICAR se puede encontrar aquí: http://www.postgresql.org/docs/9.0/static/sql-notify.html

En ella, se menciona esto sobre pg_notify(), lo que me hace asumir que no habría nada drásticamente diferente.

pg_notify Para enviar una notificación también se puede utilizar la función de pg_notify (texto, texto). La función toma el nombre del canal como primer argumento y la carga como el segundo. La función es mucho más fácil de usar que el comando NOTIFY si necesita trabajar con nombres de canal no constantes y cargas útiles.

Gracias como siempre por la ayuda

Edición: Versión de base de datos es: "PostgreSQL 9.0.3 en i686-pc-linux-gnu, compilado por GCC GCC (GCC) 4.2.4, 32- bit "

+0

¿Qué versión de postgresql está usando? ¡SELECCIONE la versión()! – Daniel

+0

¿Ingresa 'LISTEN my_channel;' 'SELECT pg_notify ('my_channel', 'my message text');' en una sesión psql no genera nada? Para mí, el resultado de pg_notify va acompañado de un mensaje de "Notificación asincrónica ...". – araqnid

+0

Gracias araqnid, ¡esto me ayudó a asegurarme que no me estaba volviendo loco! Desafortunadamente, también me ayuda a parecer un poco estúpido. O bien. Mi respuesta esta abajo – Abstrct

Respuesta

21

He discutido esto en la lista de correo de PostgreSQL (http://archives.postgresql.org/pgsql-bugs/2011- 03/msg00041.php) y se le informó sobre el razonamiento del comportamiento.

Su respuesta es que" .you que duplicar relnames cotización (escuchan 'Test'). si desea que el servidor no distingue entre mayúsculas y doblarlas. Pg_notify toma una cadena, no un nombre_rel , que utiliza diferentes normas ."(Gracias Merlin y Tom)

Esto significa que las siguientes obras porque el canal siempre se ve obligado a minúsculas

LISTEN ERRORCHANNEL; 

NOTIFY ERRORCHANNEL, 'something!'; 
NOTIFY eRrorChanNel, 'something!'; 

Si se va a añadir comillas dobles alrededor del nombre del canal, se mantendría el caso .

Así, con la siguiente, que recibiría la primera notificación, pero no el segundo:

LISTEN "ERRORCHANNEL"; 

NOTIFY "ERRORCHANNEL", 'something!'; 
NOTIFY "eRrorChanNel", 'something!'; 

del mismo modo, el siguiente va a funcionar porque XX e comillas fuerzan el caso de ERRORCHANNEL ser mantenido:

LISTEN "ERRORCHANNEL"; 

SELECT pg_notify('ERRORCHANNEL', 'something!'); 

Si bien esto no funcionará:

LISTEN ERRORCHANNEL; 

SELECT pg_notify('ERRORCHANNEL', 'something!'); 

En esta situación ERRORCHANNEL no está entre comillas dobles en el comando escuchar para PostgreSQL lo obliga a minúscula. El parámetro de canal es de tipo texto en lugar de relname, por lo que el caso no se modifica en la función pg_notify(). Juntos, los canales no coinciden (ERRORCHANNE! = Errorchannel) por lo que la notificación nunca se recibe.

-1

Si está haciendo esto desde su aplicación, necesita sondear activamente la base de datos para nuevas notificaciones.

No hay "empuje" del servidor al cliente.

En JDBC tiene que ejecutar algún tipo de instrucción SELECT y luego ninguna notificación pendiente estará disponible en el objeto de conexión (ver http://jdbc.postgresql.org/documentation/head/listennotify.html)

No sé cómo funciona esto para otros lenguajes de programación. Creo que libpq (C/C++) tiene funciones especiales para recuperar directamente las notificaciones sin ejecutar una selección

+0

Tengo un pequeño script de python que sondea el servidor para nuevas notificaciones. Usar el comando NOTIFY funciona perfectamente. Es solo la función pg_notify (texto, texto) que no funciona. – Abstrct

+17

There * is * a push del servidor al cliente. Es solo que algunos adaptadores de bases de datos de clientes no pueden manejar tales notificaciones de forma asincrónica. libpq y psycopg2 por ejemplo * can *, si integra la conexión fd en su propio bucle 'select()' o similar. – intgr

Cuestiones relacionadas