自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

巧用CAS解決數(shù)據(jù)一致性問題

開發(fā) 開發(fā)工具
在高并發(fā)的分布式環(huán)境下,對于數(shù)據(jù)的查詢與修改容易引發(fā)一致性問題,本文將分享一種非常簡單但有效的優(yōu)化方法。

[[177350]]

在高并發(fā)的分布式環(huán)境下,對于數(shù)據(jù)的查詢與修改容易引發(fā)一致性問題,本文將分享一種非常簡單但有效的優(yōu)化方法。

一、業(yè)務(wù)場景

業(yè)務(wù)場景為,購買商品的過程要對余額進(jìn)行查詢與修改,大致的業(yè)務(wù)流程如下:

(1)從數(shù)據(jù)庫查詢用戶現(xiàn)有余額 SELECT money FROM t_yue WHERE uid=$uid,不妨設(shè)查詢出來的$old_money=100元

從數(shù)據(jù)庫查詢用戶現(xiàn)有余額

(2)業(yè)務(wù)層實施業(yè)務(wù)邏輯,比如購買一個80元的商品,并且打九折

if($old_money> 80*0.9) $new_money=$old_money-80*0.9=28

業(yè)務(wù)層實施業(yè)務(wù)邏輯

(3)將數(shù)據(jù)庫中的余額進(jìn)行修改 UPDAtE t_yue SET money=$new_money WHERE uid=$uid

將數(shù)據(jù)庫中的余額進(jìn)行修改

在并發(fā)量低的情況下,這個流程沒有任何問題,原有金額100元,購買了80元的九折商品(72元),剩余28元。

二、潛在的問題

在分布式環(huán)境中,如果并發(fā)量很大,這種“查詢+修改”的業(yè)務(wù)很容易出現(xiàn)數(shù)據(jù)不一***限情況下,可能出現(xiàn)這樣的異常流程:

(1)業(yè)務(wù)1和業(yè)務(wù)2同時查詢余額,是100元

高并發(fā)的分布式環(huán)境下,可能出現(xiàn)的異常流程

(2)業(yè)務(wù)1和業(yè)務(wù)2進(jìn)行邏輯計算,算出各自業(yè)務(wù)的余額,假設(shè)業(yè)務(wù)1算出的余額是28元,業(yè)務(wù)2算出的余額是38元

高并發(fā)的分布式環(huán)境下,可能出現(xiàn)的異常流程

(3)業(yè)務(wù)1對數(shù)據(jù)庫中的余額先進(jìn)行修改,設(shè)置成28元。

業(yè)務(wù)2對數(shù)據(jù)庫中的余額后進(jìn)行修改,設(shè)置成38元。

高并發(fā)的分布式環(huán)境下,可能出現(xiàn)的異常流程

此時異常出現(xiàn)了,原有金額100元,業(yè)務(wù)1扣除了72元,業(yè)務(wù)2扣除了62元,***剩余38元。

三、問題原因

高并發(fā)環(huán)境下,對同一個數(shù)據(jù)的并發(fā)讀(兩邊都讀出余額是100)與并發(fā)寫(一個寫回28,一個寫回38)導(dǎo)致的數(shù)據(jù)一致性問題。

四、原因分析

業(yè)務(wù)1的寫回:原有金額100,這是一個初始狀態(tài),寫回金額28,理論上只有在原有金額為100的時候才允許寫回成功,這一步?jīng)]問題。

業(yè)務(wù)2的寫回:的原有金額100,這是一個初始狀態(tài),寫回金額38,理論上只有在原有金額為100的時候才允許寫回成功,可實際上,這個時候數(shù)據(jù)庫中的金額已經(jīng)變?yōu)?8了,這一步的寫操作不應(yīng)該成功。

五、簡易解決方案

在set寫回的時候,加上初始狀態(tài)的條件compare,只有初始狀態(tài)不變時,才允許set寫回成功,這正是大家常說的“Compare And Set”(CAS),是一種常見的降低讀寫鎖沖突,保證數(shù)據(jù)一致性的方法。

六、業(yè)務(wù)的升級

業(yè)務(wù)線使用CAS解決高并發(fā)時數(shù)據(jù)一致性問題,只需要在進(jìn)行set操作時,compare一下初始值,如果初始值變換,不允許set成功。

對于上文中的業(yè)務(wù)場景,只需要將“UPDAtEt_yue SET money=$new_money WHERE uid=$uid”升級為

“UPDAtE t_yue SETmoney=$new_money WHERE uid=$uid AND money=$old_money”即可。

并發(fā)操作發(fā)生時:

業(yè)務(wù)1執(zhí)行 => UPDAtE t_yue SET money=28 WHERE uid=$uid AND money=100

業(yè)務(wù)2執(zhí)行 => UPDAtE t_yue SET money=38 WHERE uid=$uid AND money=100

【這兩個操作同時進(jìn)行時,只能有一個執(zhí)行成功】。

七、怎么判斷哪個執(zhí)行成功,哪個執(zhí)行失敗

set操作,其實無所謂成功或者失敗,業(yè)務(wù)能通過affect rows得知哪個修改沒有成功:

執(zhí)行成功的業(yè)務(wù),affect rows為1

執(zhí)行失敗的業(yè)務(wù),affect rows為0

八、總結(jié)

 

高并發(fā)“查詢并修改”的場景,可以用CAS(Compare and Set)的方式解決數(shù)據(jù)一致性問題。對應(yīng)到業(yè)務(wù),即在set的時候,加上初始條件的比對。

【本文為51CTO專欄作者“58沈劍”原創(chuàng)稿件,轉(zhuǎn)載請聯(lián)系原作者】

責(zé)任編輯:趙寧寧 來源: 架構(gòu)師之路
相關(guān)推薦

2022-06-21 21:47:13

數(shù)據(jù)系統(tǒng)

2023-08-01 07:42:33

Redis數(shù)據(jù)項目

2012-09-24 09:35:42

分布式系統(tǒng)

2019-05-27 09:00:00

蘇寧智慧零售平臺數(shù)據(jù)庫

2022-05-31 08:37:59

RedisMySQL數(shù)據(jù)一致性

2024-04-11 13:45:14

Redis數(shù)據(jù)庫緩存

2022-09-06 15:30:20

緩存一致性

2024-11-14 07:10:00

2022-08-11 07:55:05

數(shù)據(jù)庫Mysql

2018-10-25 14:40:23

分布式數(shù)據(jù)數(shù)據(jù)不一致

2024-12-26 15:01:29

2023-09-07 08:11:24

Redis管道機(jī)制

2025-03-27 08:20:54

2020-09-04 06:32:08

緩存數(shù)據(jù)庫接口

2023-06-29 08:00:59

redis數(shù)據(jù)MySQL

2021-12-05 21:06:27

軟件

2022-02-17 21:04:27

數(shù)據(jù)庫MysqlRedis

2021-10-13 09:55:11

流計算引擎數(shù)據(jù)

2009-06-18 09:18:08

Oracle檢索數(shù)據(jù)數(shù)據(jù)一致性事務(wù)恢復(fù)

2021-10-18 10:30:59

流計算阿里云
點贊
收藏

51CTO技術(shù)棧公眾號