Postgresql 的 pg_notify 方法介紹

今日看了這篇博文: 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');



pg_notify方法的第一個參數是Channel,第二個方法就是要發送的內容,很是簡單。

一當執行這條SQL的時候,幾乎同時在golang的程序就會打印出如下結果: spa

是否是以爲很神奇?反正我是,哈哈。 code

經過PG的這個機制,咱們就可讓數據庫」主動「地告訴咱們什麼數據更新了,從而能夠觸發其它動做。 中間件

不過這個機制只是相似於消息中間件的功能,但畢竟不是,它不會幫你存儲消息,更不會持久化。當PG把消息發出去後,它是不會管是否有被監聽的。換句話說,若是監聽程序是在消息發送以前啓動,它是不會得到之前的消息的。這點卻是要注意。若是對這一個特色比較介意的話,建議多開幾個監聽程序,或者用其它的方法來實現真正的消息中間件功能。

相關文章
相關標籤/搜索