golang簡單key/value資料庫(二)
上一章的鏈接在此:golang簡單key/value資料庫(一)
上一章建立的資料庫,雖然是建立在http上,高並發的,但並不是並發安全的。
原因是我們使用map來儲存key-value的值,map是引用傳遞的、如果多個goroutine同時讀寫,必然導致衝突。
解決辦法三種:
- 給map加鎖,加排斥鎖;
- 利用channel隊列;
- 使用其他數據結構,例如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。
下一章,解決數據持久化。
推薦閱讀: