golang簡單key/value資料庫(二)

上一章的鏈接在此:golang簡單key/value資料庫(一)

上一章建立的資料庫,雖然是建立在http上,高並發的,但並不是並發安全的。

原因是我們使用map來儲存key-value的值,map是引用傳遞的、如果多個goroutine同時讀寫,必然導致衝突。

解決辦法三種:

  1. 給map加鎖,加排斥鎖;
  2. 利用channel隊列;
  3. 使用其他數據結構,例如b tree、b+tree、hashmap等。

這裡主要是講第一種解決方法:

//router.go //原本的cache換成帶Mutex的結構體type Cache struct { Data map[string]string Mutex *sync.RWMutex}

注意:在聲明Cache的時候,一定要傳Mutex的引用,不然默認淺拷貝,還是會出現並發安全問題。

//main.gocache := router.Cache{Data:make(map[string]string),Mutex: &sync.Mutex{}}

上鎖了之後記得要解鎖,不然會造成死鎖:

//router.gofunc (cache Cache) post(r *http.Request) string { var response map[string]string body, err := ioutil.ReadAll(r.Body) if err != nil { panic(err) } err = json.Unmarshal(body, &response) if err != nil { panic(err) } if len(response) == 0 { return "none json in body" } //上鎖 cache.Mutex.Lock() //記得解鎖,以免造成死鎖 defer cache.Mutex.Unlock() for k, v := range response { if _, ok := cache.Data[k]; ok { return k + "%s already exist" } cache.Data[k] = v } return "success"}

詳細代碼:參見github。

下一章,解決數據持久化。


推薦閱讀:

TAG:Go語言 | 資料庫 | 高並發 |