tl;dr
Tcn provides a native trigger function to send notifications about INSERT, UPDATE and DELETEs on any table it is attached to, to subscribers of an arbitrarily named channel via PostgreSQL's NOTIFY/LISTEN mechanism. This is useful e.g. for refreshing caches automagically.
First, tcn must be installed in the database:
CREATE EXTENSION tcn;
Now, a test table is created:
CREATE TABLE public.cats
(
id serial NOT NULL,
face_name text NOT NULL,
CONSTRAINT cats_pkey PRIMARY KEY (face_name)
)
WITH (
OIDS=FALSE
);
And the trigger:
CREATE TRIGGER cats_tcn_trigger
AFTER INSERT OR UPDATE OR DELETE ON cats
FOR EACH ROW EXECUTE PROCEDURE triggered_change_notification('cats');
Here, the channel is named 'cats'. If the parameter is omitted, the channel is 'tcn' by default.
It's all set, now we can subscribe to channel 'cats':
LISTEN cats;
Now, when we INSERT some data, the following happens:
INSERT INTO cats (face_name) VALUES ('Tailchaser');
Query returned successfully: one row affected, 13 msec execution time.
Asynchronous notification of 'cats' received from backend pid 5457
Data: "cats",I,"face_name"='Tailchaser'
Multiple operations generate multiple notifications:
INSERT INTO cats (face_name) VALUES ('Hushpad'),('Pouncequick');
Query returned successfully: 2 rows affected, 11 msec execution time.
Asynchronous notification of 'cats' received from backend pid 5457
Data: "cats",I,"face_name"='Hushpad'
Asynchronous notification of 'cats' received from backend pid 5457
Data: "cats",I,"face_name"='Pouncequick'
But what is this good for?
Well, some PostgreSQL drivers support asynchronous notification, e.g. libpq for C, psycopg2 for Python or JDBC for Java. So this can be used for notifying all clients if the content of a table has been changed.
Then the client can react accordingly, e.g. refresh the cache of such a table, or display the changes in a (near) real-time information system, or whatever action is required in the context of the application if a change has occurred.
The following Python code shows an example matching the 'cats' table from above.
Start with python notify.py:
Waiting for notifications on channel 'cats'
INSERT INTO cats (face_name) VALUES ('Roofshadow');
yields
Got NOTIFY: 5457 cats "cats",I,"face_name"='Roofshadow'
Must refresh cache
As always, imagination is the limit.
No comments:
Post a Comment