memcachedを使って排他制御を行う
例: ISUCON9 予選問題 (POST /buy)
トランザクション貼ったりAPIリクエスト投げたりしててデッドロックの温床
デッドロックしまくって点数がなかなか稼げない
トランザクションに入る前にアプリケーションで排他制御を行うことでデッドロックを回避できる
ほんとうはCAS命令を使わないといけなそう? あとで書き直してみる
code:main.go
mc := memcache.New("127.0.0.1:11211")
// lock
mutexKey := fmt.Sprintf("mutex:item:%d", rb.ItemID)
retry := 0
for {
_, err = mc.Get(mutexKey)
if err != memcache.ErrCacheMiss {
if retry > 5 {
outputErrorMsg(w, http.StatusForbidden, "item is not for sale")
return
}
time.Sleep(800 * time.Millisecond) // 秒数は適当
retry++
continue
}
break
}
mc.Set(&memcache.Item{Key: mutexKey, Value: []byte{1}})
defer mc.Delete(mutexKey)
tx := dbx.MustBegin()
// ...
参考
increment, decrementでmutexを実装してる