| PostgreSQL: Das Offizielle Handbuch | ||||
|---|---|---|---|---|
| Zurück | Schnell zurück | Schnell nach vorne | Nach vorne | |
Der Befehl NOTIFY sendet eine Benachrichtigung an jede Clientanwendung, die zuvor LISTEN name für den angegebenen Benachrichtigungsnamen in der aktuellen Datenbank ausgeführt hat.
Die dem Client bei einer Benachrichtigung übergebenen Informationen bestehen aus dem Benachrichtigungsnamen und der PID des Serverprozesses, der zu der Sitzung gehört, die die Benachrichtigung ausgelöst hat. Es liegt am Datenbankentwickler, die Benachrichtigungsnamen zu bestimmen, die in einer Datenbank verwendet werden, und was jeder Name bedeutet.
Gewöhnlich ist der Name der Benachrichtigung der gleiche wie der Name einer Tabelle in der Datenbank und die Benachrichtigung sagt im Prinzip aus: „Ich habe diese Tabelle verändert, schaut nach, was neu ist“. Aber die Befehle NOTIFY und LISTEN erzwingen keine derartigen Zusammenhänge. Ein Datenbankentwickler könnte zum Beispiel mehrere verschiedene Benachrichtigungsnamen vorsehen um verschiedene Arten von Änderungen in einer einzigen Tabelle anzuzeigen.
NOTIFY stellt Prozessen, die auf die selbe PostgreSQL-Datenbank zugreifen, eine einfache Form von Signalen oder Interprozesskommunikation zur Verfügung. Leistungsfähigere Mechanismen können gebaut werden, indem Tabellen in der Datenbank verwendet werden, um zusätzliche Daten (anstatt nur den Benachrichtigungsnamen) vom Auslöser an die Zuhörer zu übergeben.
Wenn NOTIFY verwendet werden soll um Veränderungen in einer bestimmten Tabelle mitzuteilen, dann ist es sinnvoll, den NOTIFY-Befehl von einer Regel ausführen zu lassen, die von entsprechenden Befehlen, die die Tabelle aktualisieren, ausgelöst wird. Dadurch werden die Benachrichtigungen automatisch ausgelöst, wenn die Tabelle geändert wird, und der Anwendungsprogrammierer kann es nicht aus Versehen vergessen.
NOTIFY hat einige wichtige Wechselwirkungen mit SQL-Transaktionen. Erstens, wenn NOTIFY in einer Transaktion ausgeführt wird, dann werden die Benachrichtigungen erst und nur abgeschickt, wenn die Transaktion erfolgreich abgeschlossen wird. Das ist sinnvoll, denn wenn die Transaktion abgebrochen würden, dann sollten alle darin enthaltenen Befehle, einschließlich des NOTIFY, ohne Auswirkung bleiben. Es kann aber verwirrend sein, wenn man erwartet, dass die Benachrichtigungen sofort abgeschickt werden. Zweitens, wenn eine zuhörende Sitzung eine Benachrichtigung erhält, während sie sich in einer Transaktion befindet, dann wird die Benachrichtigung erst an den Client weitergegeben, wenn die Transaktion beendet ist (erfolgreich abgeschlossen oder abgebrochen). Der Grund ist wiederum, dass eine Benachrichtigung, die in einer Transaktion ankommt, die später abgebrochen wird, irgendwie zurückgenommen werden sollte -- aber der Server kann keine Benachrichtigungen stornieren, wenn Sie schon an den Client gesendet worden ist. Also werden Benachrichtigungen nur zwischen Transaktionen versendet. Die Konsequenz daraus ist, dass Anwendungen, die mit NOTIFY Signale in Echtzeit austauschen wollen, ihre Transaktionen kurz halten sollten.
NOTIFY verhält sich in einer Hinsicht wie Unix-Signale: Wenn Benachrichtigungen mit dem gleichen Namen in kurzen Abständen erzeugt werden, dann kann es sein, dass die Empfänger nur eine Benachrichtigung bei mehreren Aufrufen von NOTIFY empfangen. Man sollte sich also nicht auf die Anzahl der empfangenen Benachrichtigungen verlassen. Stattdessen sollte man NOTIFY nur verwenden, um Anwendungen, deren Aufmerksamkeit man wünscht, aufzuwecken, und dann ein Datenbankobjekt (zum Beispiel eine Sequenz) verwenden um festzuhalten, was passiert ist oder wie oft es passiert ist.
Es ist nicht ungewöhnlich, dass ein Client, der NOTIFY ausführt, selbst auf diesen Benachrichtigungsnamen hört. In diesem Fall erhält auch er eine Benachrichtigung wie alle anderen darauf wartenden Sitzungen. Je nach Anwendungsaufbau ergibt sich daraus nutzlose Arbeit, zum Beispiel beim erneuten Lesen einer Datenbanktabelle, die gerade selbst geschrieben wurde. Solche nutzlose Arbeit kann man vermeiden, indem man die PID des Serverprozesses der Sitzung, die die Benachrichtigung erzeugt hat (in der Benachrichtigungsmitteilung enthalten) mit der PID des Serverprozesses der eigenen Sitzung (in libpq verfügbar) vergleicht. Wenn sie gleich sind, dann ist die Benachrichtigung die eigene zurückgekommene und kann ignoriert werden. (Trotz der Aussagen im vorangegangenen Absatz ist diese Technik sicher. PostgreSQL hält die Selbstbenachrichtigungen von denen aus anderen Sitzungen getrennt, also können Sie keine Benachrichtigungen von anderen Sitzungen verpassen, wenn Sie ihre eigenen ignorieren.)
Der Name der Benachrichtigungsmitteilung, die ausgelöst werden soll (ein beliebiger SQL-Bezeichner).
So sieht es in psql aus, wenn man sich für eine Benachrichtigung registriert und sie dann selbst auslöst:
LISTEN virtual; NOTIFY virtual; Asynchronous NOTIFY 'virtual' from backend with pid '8448' received.
| Zurück | Zum Anfang | Nach vorne |
| MOVE | Nach oben | PREPARE |