標籤:
今日看了這篇博文:
https://medium.com/namely-labs/syncing-cache-with-postgres-7a4d78cec022
再一次感歎PG的強大。原來PG還可以通過pg_notify 這個方法,再加上觸發器,去主動告訴外界資料的變化。
看了博文後,就用golang自己照著例子寫了一個,以供參考:
package mainimport ("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.Notifyswitch 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 方法介紹