今日看了这篇博文: git
https://medium.com/namely-labs/syncing-cache-with-postgres-7a4d78cec022 github
再一次感叹PG的强大。原来PG还能够经过pg_notify 这个方法,再加上触发器,去主动告诉外界数据的变化。 golang
看了博文后,就用golang本身照着例子写了一个,以供参考: sql
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方法,只接受字符串,但愿之后能够扩展,那样就不用再作数据类型的转换了。 post
当这个golang程序跑起来后,怎么测试效果呢? 最简单的方法,就是用pgAdmin链接到咱们程序中的数据库,打开一个Query窗口,而后输入如下的命令并执行: 测试
select pg_notify('hello', 'world');
一当执行这条SQL的时候,几乎同时在golang的程序就会打印出如下结果: spa
是否是以为很神奇?反正我是,哈哈。 code
经过PG的这个机制,咱们就可让数据库”主动“地告诉咱们什么数据更新了,从而能够触发其它动做。 中间件
不过这个机制只是相似于消息中间件的功能,但毕竟不是,它不会帮你存储消息,更不会持久化。当PG把消息发出去后,它是不会管是否有被监听的。换句话说,若是监听程序是在消息发送以前启动,它是不会得到之前的消息的。这点却是要注意。若是对这一个特色比较介意的话,建议多开几个监听程序,或者用其它的方法来实现真正的消息中间件功能。