1.業務層面樂觀鎖CAS,使用版本號解決ABA問題,實際使用中使用時間戳,更新的時候把查出來的時間戳帶上,若是更新失敗能夠自旋,獲取最近值和時間戳,直到更新成功。
2.DB層面開啓一個事務,而後select一行for update給這一行加上排它鎖,再去更新行,而後提交,其餘事務就會阻塞在select for update。
3.分佈式鎖適合競爭不激烈的狀況保證一致性,由於性能比較差,按CAP理論來說應該是保證了CP放棄了A,zk或者redis保證一致性P,只有拿到鎖的線程才能執行,保證一致性C。
4.採用redis方式的分佈式鎖,若是有集羣,當主掛了以後,還未同步到從,那麼另外的線程會到從庫拿鎖,引發超賣問題。根本緣由是,分佈式鎖要求的是CP,redis集羣是AP,用AP去實現CP是不現實的。
5.redis方式還有一個問題,setnx超時時間若是小於接口超時時間,當接口緩慢時達到redis超時時間會釋放鎖,再來請求就會拿到鎖,會出現多個用戶同時拿到鎖。
6.用redis自己的原子性操做庫存是一種常見作法。
// redis會返回操做以後的結果,這個過程是原子性的
Long currStock = redisTemplate.opsForHash().increment("key", "stock", -1);
if (currStock < 0) { // 說明庫存已經扣減完了。
// 業務異常。
log.error("[搶購下單] 無庫存");
} else {
// 生成訂單
// 發佈訂單建立成功事件
// 構建響應
}redis