開篇數據庫
同一個用戶併發扣款時,有必定機率出現數據不一致,可使用CAS樂觀鎖的方式,在不下降吞吐量,保證數據的一致性:架構
不能採用直接扣減的方式:併發
固然,更通用的方式,可使用版本號來實現CAS樂觀鎖:高併發
對於這個CAS樂觀鎖方案,頗有朋友有疑問:當併發量高時,版本號比對會致使大量的更新失敗,這個方案不適用於高併發場景嗎? 到底是不是這樣呢?你們對高併發是否是有什麼誤解呢?今天來聊一聊這個話題。
先分析三個業務場景。 學習
1、QQ優化
QQ的一些核心業務有:ui
我的:user(uid, user_info, …)orm
好友:user_friends(uid, friend_id, …)cdn
加入的羣:user_groups(uid, group_id, …)排序
羣:group(gid, group_info, …)
羣成員:group_members(gid, uid, …)
我的消息:msgs_user(msg_id, uid, …)
羣消息:msgs_group(msg_id, gid, …)
這些信息的讀寫有一個特色,都會帶上uid/gid/msgid屬性。
例如,拉取好友列表:
在用戶量很大,併發量很大時,不一樣用戶/羣/消息數據的讀寫並無鎖衝突。
只有當,同一個用戶,很短的時間內,有大量併發時,纔可能存在鎖衝突。
2、微博微博的核心業務是feed流:
發消息,寫操做
刷消息,讀操做
微博業務顯然是讀多寫少的,在用戶刷消息時,本身feed流裏的消息,是由別人發出的。
查看本身主頁feed流,最樸素的實現方法是:
(1) 拉取本身關注的用戶id_list;
(2) 拉取這些用戶最近N條消息;
(3) 將這N*id_list條消息排序;
(4) 返回第一頁消息,獲得本身主頁feed流;
3、1230612306的核心業務是:
查票,讀操做
買票,寫操做
在用戶量很大,併發量很大時,有極大的鎖衝突。
收尾
QQ,微博、12306,一樣是高併發業務,就數據存儲鎖衝突來講,各自的難度,數據不一致的機率是不一樣的。
回到開篇,使用CAS樂觀鎖進庫存扣減:
只要有uid這個過濾屬性,即便10W用戶同時扣款,也不容易出現數據不一致。 只有當同一個用戶,同一秒鐘,有大量扣減時,纔有必定概率會衝撞,但也不會致使數據不一致。
結論
高併發的扣款場景,可使用CAS樂觀鎖,採用select&set方式進行扣款,既可以保證吞吐量,又可以保證一致性。
歡迎關注公衆號:「Java架構師學習」
你會喜歡的!