feat: 为用到缓存的部分套上了防击穿锁

This commit is contained in:
Leon
2025-12-24 14:09:10 +08:00
parent 0d34f2abee
commit a7c6525f57
2 changed files with 150 additions and 36 deletions

View File

@@ -69,6 +69,37 @@ func (vs *VideoService) GetDetail(ctx context.Context, id uint) (*Video, error)
if err := json.Unmarshal(b, &cached); err == nil {
return &cached, nil
}
} else if rediscache.IsMiss(err) {
lockKey := "lock:" + cacheKey
token, locked, _ := vs.cache.Lock(cacheCtx, lockKey, 500*time.Millisecond)
if locked {
defer func() { _ = vs.cache.Unlock(context.Background(), lockKey, token) }()
if b, err := vs.cache.GetBytes(cacheCtx, cacheKey); err == nil {
var cached Video
if err := json.Unmarshal(b, &cached); err == nil {
return &cached, nil
}
} else { // 缓存未命中,从数据库中查询
video, err := vs.repo.GetByID(ctx, id)
if err != nil {
return nil, err
}
if b, err := json.Marshal(video); err == nil {
_ = vs.cache.SetBytes(cacheCtx, cacheKey, b, vs.cacheTTL)
}
return video, nil
}
} else { // 缓存未命中其他goroutine正在查询等待
for i := 0; i < 5; i++ {
time.Sleep(20 * time.Millisecond)
if b, err := vs.cache.GetBytes(cacheCtx, cacheKey); err == nil {
var cached Video
if err := json.Unmarshal(b, &cached); err == nil {
return &cached, nil
}
}
}
}
}
}