日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

MySQL中SELECT+UPDATE處理并發(fā)更新問(wèn)題解決方案

瀏覽:31日期:2023-10-17 08:07:13

這篇文章主要介紹了MySQL中SELECT+UPDATE處理并發(fā)更新問(wèn)題解決方案分享,需要的朋友可以參考下。

問(wèn)題背景

假設(shè)MySQL數(shù)據(jù)庫(kù)有一張會(huì)員表vip_member(InnoDB表),結(jié)構(gòu)如下:

MySQL中SELECT+UPDATE處理并發(fā)更新問(wèn)題解決方案

當(dāng)一個(gè)會(huì)員想續(xù)買(mǎi)會(huì)員(只能續(xù)買(mǎi)1個(gè)月、3個(gè)月或6個(gè)月)時(shí),必須滿足以下業(yè)務(wù)要求:

如果end_at早于當(dāng)前時(shí)間,則設(shè)置start_at為當(dāng)前時(shí)間,end_at為當(dāng)前時(shí)間加上續(xù)買(mǎi)的月數(shù)如果end_at等于或晚于當(dāng)前時(shí)間,則設(shè)置end_at=end_at+續(xù)買(mǎi)的月數(shù)續(xù)買(mǎi)后active_status必須為1(即被激活)問(wèn)題分析

對(duì)于上面這種情況,我們一般會(huì)先SELECT查出這條記錄,然后根據(jù)查出記錄的end_at再UPDATE start_at和end_at,偽代碼如下(為uid是1001的會(huì)員續(xù)1個(gè)月):

vipMember = SELECT * FROM vip_member WHERE uid=1001 LIMIT 1 # 查uid為1001的會(huì)員 if vipMember.end_at < NOW(): UPDATE vip_member SET start_at=NOW(), end_at=DATE_ADD(NOW(), INTERVAL 1 MONTH), active_status=1, updated_at=NOW() WHERE uid=1001 else: UPDATE vip_member SET end_at=DATE_ADD(end_at, INTERVAL 1 MONTH), active_status=1, updated_at=NOW() WHERE uid=1001

假如同時(shí)有兩個(gè)線程執(zhí)行上面的代碼,很顯然存在“數(shù)據(jù)覆蓋”問(wèn)題(即一個(gè)是續(xù)1個(gè)月,一個(gè)續(xù)2個(gè)月,但最終可能只續(xù)了2個(gè)月,而不是加起來(lái)的3個(gè)月)。

解決方案

A、我想到的第一種方案是把SELECT和UPDATE合成一條SQL

如下:

UPDATE vip_member SET start_at = CASE WHEN end_at < NOW() THEN NOW()ELSE start_atEND, end_at = CASEWHEN end_at < NOW()THEN DATE_ADD(NOW(), INTERVAL #duration:INTEGER# MONTH)ELSE DATE_ADD(end_at, INTERVAL #duration:INTEGER# MONTH)END, active_status=1, updated_at=NOW()WHERE uid=#uid:BIGINT#LIMIT 1;

B、第二種方案:事務(wù),即用一個(gè)事務(wù)來(lái)包裹上面的SELECT+UPDATE操作

那么是否包上事務(wù)就萬(wàn)事大吉了呢?

顯然不是。因?yàn)槿绻瑫r(shí)有兩個(gè)事務(wù)都分別SELECT到相同的vip_member記錄,那么一樣的會(huì)發(fā)生數(shù)據(jù)覆蓋問(wèn)題。那有什么辦法可以解決呢?難道要設(shè)置事務(wù)隔離級(jí)別為SERIALIZABLE,考慮到性能不現(xiàn)實(shí)。

我們知道InnoDB支持行鎖。查看MySQL官方文檔(innodb locking reads)了解到InnoDB在讀取行數(shù)據(jù)時(shí)可以加兩種鎖:讀共享鎖和寫(xiě)?yīng)氄兼i。

讀共享鎖是通過(guò)下面這樣的SQL獲得的:

SELECT * FROM parent WHERE NAME = ’Jones’ LOCK IN SHARE MODE;

如果事務(wù)A獲得了先獲得了讀共享鎖,那么事務(wù)B之后仍然可以讀取加了讀共享鎖的行數(shù)據(jù),但必須等事務(wù)A commit或者roll back之后才可以更新或者刪除加了讀共享鎖的行數(shù)據(jù)。

SELECT counter_field FROM child_codes FOR UPDATE;UPDATE child_codes SET counter_field = counter_field + 1;

如果事務(wù)A先獲得了某行的寫(xiě)共享鎖,那么事務(wù)B就必須等待事務(wù)A commit或者roll back之后才可以訪問(wèn)行數(shù)據(jù)。

顯然要解決會(huì)員狀態(tài)更新問(wèn)題,不能加讀共享鎖,只能加寫(xiě)共享鎖,即將前面的SQL改寫(xiě)成如下:

vipMember = SELECT * FROM vip_member WHERE uid=1001 LIMIT 1 FOR UPDATE # 查uid為1001的會(huì)員if vipMember.end_at < NOW(): UPDATE vip_member SET start_at=NOW(), end_at=DATE_ADD(NOW(), INTERVAL 1 MONTH), active_status=1, updated_at=NOW() WHERE uid=1001else: UPDATE vip_member SET end_at=DATE_ADD(end_at, INTERVAL 1 MONTH), active_status=1, updated_at=NOW() WHERE uid=1001

另外這里特別提醒下:UPDATE/DELETE SQL盡量帶上WHERE條件并在WHERE條件中設(shè)定索引過(guò)濾條件,否則會(huì)鎖表,性能可想而知有多差了。

C、第三種方案:樂(lè)觀鎖,類(lèi)CAS機(jī)制

第二種加鎖方案是一種悲觀鎖機(jī)制。而且SELECT...FOR UPDATE方式也不太常用,聯(lián)想到CAS實(shí)現(xiàn)的樂(lè)觀鎖機(jī)制,于是我想到了第三種解決方案:樂(lè)觀鎖。

具體來(lái)說(shuō)也挺簡(jiǎn)單,首先SELECT SQL不作任何修改,然后在UPDATE SQL的WHERE條件中加上SELECT出來(lái)的vip_memer的end_at條件。如下:

vipMember = SELECT * FROM vip_member WHERE uid=1001 LIMIT 1 # 查uid為1001的會(huì)員cur_end_at = vipMember.end_atif vipMember.end_at < NOW(): UPDATE vip_member SET start_at=NOW(), end_at=DATE_ADD(NOW(), INTERVAL 1 MONTH), active_status=1, updated_at=NOW() WHERE uid=1001 AND end_at=cur_end_atelse: UPDATE vip_member SET end_at=DATE_ADD(end_at, INTERVAL 1 MONTH), active_status=1, updated_at=NOW() WHERE uid=1001 AND end_at=cur_end_at

這樣可以根據(jù)UPDATE返回值來(lái)判斷是否更新成功,如果返回值是0則表明存在并發(fā)更新,那么只需要重試一下就好了。

方案比較

三種方案各自優(yōu)劣也許眾說(shuō)紛紜,只說(shuō)說(shuō)我自己的看法:

第一種方案利用一條比較復(fù)雜的SQL解決問(wèn)題,不利于維護(hù),因?yàn)榘丫唧w業(yè)務(wù)糅在SQL里了,以后修改業(yè)務(wù)時(shí)不但需要讀懂這條SQL,還很有可能會(huì)修改成更復(fù)雜的SQL第二種方案寫(xiě)?yīng)氄兼i,可以解決問(wèn)題,但不常用第三種方案應(yīng)該是比較中庸的解決方案,并且甚至可以不加事務(wù),也是我個(gè)人推薦的方案

此外,樂(lè)觀鎖和悲觀鎖的選擇一般是這樣的(參考了文末第二篇資料):

如果對(duì)讀的響應(yīng)度要求非常高,比如證券交易系統(tǒng),那么適合用樂(lè)觀鎖,因?yàn)楸^鎖會(huì)阻塞讀如果讀遠(yuǎn)多于寫(xiě),那么也適合用樂(lè)觀鎖,因?yàn)橛帽^鎖會(huì)導(dǎo)致大量讀被少量的寫(xiě)阻塞如果寫(xiě)操作頻繁并且沖突比例很高,那么適合用悲觀寫(xiě)?yīng)氄兼i
標(biāo)簽: MySQL 數(shù)據(jù)庫(kù)
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
亚洲人成精品久久久| 日本不良网站在线观看| 久久青草久久| 日韩不卡视频在线观看| 免费看久久久| 久久精品一区二区国产| 国产一区二区三区精品在线观看| 久久成人高清| 日韩国产欧美一区二区| 日韩欧美一区二区三区免费看| 成人在线视频中文字幕| 麻豆视频在线看| 欧美aa在线观看| 樱桃成人精品视频在线播放| 视频一区二区中文字幕| 97久久亚洲| 色婷婷色综合| 99精品99| 国产精品白浆| 日本免费一区二区三区四区| 91九色精品| 日韩一区二区三区免费视频| 国产精品国码视频| 欧美日韩高清| 国产福利资源一区| 亚洲少妇诱惑| 老鸭窝一区二区久久精品| 久久精品国内一区二区三区水蜜桃| 午夜国产一区二区| 国产精品久久久久av蜜臀| 秋霞影视一区二区三区| 青青草视频一区| 欧美肉体xxxx裸体137大胆| 亚洲精品国产精品粉嫩| 国产一区二区三区四区二区| 亚洲精品2区| 精品一区二区三区四区五区| 亚洲在线成人| 精品国产精品国产偷麻豆| 三级一区在线视频先锋| 日韩电影免费网站| 九九九精品视频| 亚洲一区二区三区久久久| 蜜桃视频在线观看一区| 国产一区二区三区亚洲| 日韩精品社区| 日本天堂一区| 最新国产精品| 国产亚洲一区在线| 一区二区三区四区日本视频| 欧美亚洲综合视频| 欧美资源在线| 日本91福利区| 首页亚洲欧美制服丝腿| 婷婷亚洲综合| 午夜av一区| 久久国产成人| 免费观看在线色综合| 国产亚洲网站| 亚州精品视频| 日韩av电影一区| 欧美午夜网站| 麻豆成人91精品二区三区| 国产极品久久久久久久久波多结野| 在线国产精品一区| 日本亚洲视频在线| 欧美日韩中文| 老司机免费视频一区二区三区| 97久久超碰| 国产成人精品亚洲线观看 | 国产另类在线| 精品国产a一区二区三区v免费| 久久这里只有精品一区二区| 欧美国产三级| 蜜臀国产一区| 视频在线在亚洲| 国产一区2区在线观看| 蜜桃视频在线网站| 国产视频一区欧美| 日韩精品一区二区三区av| 国产伦理久久久久久妇女| 国产aa精品| 久久av在线| 国产精品s色| 日韩精品一区二区三区免费观影| 五月天综合网站| 国产精品66| 欧美日韩精品免费观看视频完整| 综合一区在线| 在线一区av| 日本vs亚洲vs韩国一区三区二区| 国产伦乱精品| 亚洲午夜久久久久久尤物| 日韩精品视频网| 免费黄色成人| 国产精品17p| 久久亚洲一区| 欧美日韩一区二区三区视频播放| 日韩激情一二三区| 激情视频一区二区三区| 国产午夜精品一区在线观看| 国产综合欧美| 精品国产一区二区三区av片| 久久免费视频66| 精品99久久| 国产综合精品一区| 国产模特精品视频久久久久| 亚洲一区观看| 国产精品亚洲二区| 亚洲精品乱码日韩| 美女视频一区在线观看| 国产午夜久久av| 欧美激情国产在线| 日本综合精品一区| 香蕉久久久久久久av网站| 91亚洲一区| 免费视频一区二区三区在线观看 | 欧美影院视频| av资源中文在线天堂| 91精品日本| 91大神在线观看线路一区| 亚洲麻豆一区| 亚洲三级在线| 亚洲aa在线| 日韩激情av在线| 欧美永久精品| 国产欧美午夜| 国产精品久久久久久久久久白浆 | 91欧美日韩在线| 国产精品久久久网站| 欧美综合精品| 欧美日韩夜夜| 蜜桃久久久久| 国产成人精品999在线观看| 高清日韩欧美| 成人看片网站| 在线看片不卡| 日韩欧美中文字幕在线视频| 日本不卡视频在线| 国产中文欧美日韩在线| 欧美三区四区| 热久久免费视频| 欧美在线看片| 蜜桃精品在线| 久久xxxx精品视频| 欧美日韩亚洲一区三区| 国产在线日韩精品| 国精品一区二区| 天堂va欧美ⅴa亚洲va一国产| 欧美三区不卡| 国产精品久久久久av电视剧| 黄页网站一区| 国产精品极品国产中出| 日韩久久精品网| 日韩在线电影| av高清一区| 国产视频一区二区在线播放| 亚洲天堂av影院| 欧美日韩一区二区三区四区在线观看| 国产成人精品福利| 中文久久精品| 国产一区二区三区国产精品| 99国产一区| 亚洲国产成人二区| 视频一区中文字幕精品 | 丝袜美腿成人在线| 粉嫩av一区二区三区四区五区| 国产一区二区精品| 精品一区91| 日韩国产欧美在线播放| 1024精品一区二区三区| 麻豆国产一区| 国产伦理一区| 欧美成人综合| 亚洲三级视频| av高清一区| 国产精品白丝av嫩草影院| 亚洲高清二区| 精品国产亚洲日本| 视频一区日韩| 国产精品任我爽爆在线播放| 久久久国产精品一区二区中文| 亚洲视频二区| 亚洲成人三区| 999精品一区| 国产美女高潮在线| 久久中文在线| 国产精品天堂蜜av在线播放| 99久久亚洲精品| 日韩伦理在线一区| 一区二区日韩免费看| 极品日韩av| 久久精品理论片| 国产极品久久久久久久久波多结野 | 日韩一区电影| 国产精品成人a在线观看| 国产精品亚洲综合久久| 日本在线成人| 91精品丝袜国产高跟在线| 日精品一区二区三区|