Postgresql 的 pg_notify 方法介绍

今日看了这篇博文:

https://medium.com/namely-labs/syncing-cache-with-postgres-7a4d78cec022

再一次感叹PG的强大。原来PG还可以通过pg_notify 这个方法,再加上触发器,去主动告诉外界数据的变化。

看了博文后,就用golang自己照着例子写了一个,以供参考:


package main

import (
	"database/sql"
	"fmt"
	"log"
	"time"

	"github.com/lib/pq"
)

func main() {
	uri := "user=postgres password={YOUR_PASSWORD} host={YOUR_DB_HOST} port={YOUR_DB_PORT} dbname={YOUR_DB_NAME} sslmode=disable"
	db, err := sql.Open("postgres", uri)
	if err != nil {
		log.Fatal(err)
	}

	if err := db.Ping(); err != nil {
		log.Fatal(err)
	}

	report := func(et pq.ListenerEventType, err error) {
		if err != nil {
			fmt.Println(err)
		}
	}

	listener := pq.NewListener(uri, 10*time.Second, time.Minute, report)
	err = listener.Listen("hello")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println("-------start listen------------")
	for {
		n := <-listener.Notify
		switch n.Channel {
		case "hello":
			fmt.Println("get notify : ", n.Extra)
		}
	}
}

代码的思路很简单,就是通过golang打开一个连接,然后用Listener去监听某一个Channel。在这里是一个叫"hello"的Channel。程序把Channel里面接收到的信息打印出来。 

目前PG的pg_notify方法,只接受字符串,希望以后可以扩展,那样就不用再做数据类型的转换了。

当这个golang程序跑起来后,怎么测试效果呢? 最简单的方法,就是用pgAdmin连接到我们程序中的数据库,打开一个Query窗口,然后输入以下的命令并执行:

select  pg_notify('hello', 'world');



pg_notify方法的第一个参数是Channel,第二个方法就是要发送的内容,非常简单。

一当执行这条SQL的时候,几乎同时在golang的程序就会打印出以下结果:

是不是觉得很神奇?反正我是,哈哈。

通过PG的这个机制,我们就可以让数据库”主动“地告诉我们什么数据更新了,从而可以触发其它动作。

不过这个机制只是类似于消息中间件的功能,但毕竟不是,它不会帮你存储消息,更不会持久化。当PG把消息发出去后,它是不会管是否有被监听的。换句话说,如果监听程序是在消息发送之前启动,它是不会获得以前的消息的。这点倒是要注意。如果对这一个特点比较介意的话,建议多开几个监听程序,或者用其它的方法来实现真正的消息中间件功能。






你可能感兴趣的:(Postgresql 的 pg_notify 方法介绍)