并發(fā)安全問(wèn)題之超賣(mài)問(wèn)題
樂(lè)觀鎖總結(jié):
優(yōu)點(diǎn):不加鎖性能好。
缺點(diǎn):同時(shí)請(qǐng)求成功率低(即只要發(fā)現(xiàn)數(shù)據(jù)變了就放棄了)。
樂(lè)觀鎖思想的具體體現(xiàn):一共兩步,第一步,先查詢(xún)狀態(tài)。第二步,再更新數(shù)據(jù)時(shí)必須where等于前面的狀態(tài),確保數(shù)據(jù)沒(méi)有改變。
第二步集查詢(xún)和操作數(shù)據(jù)于一身具有原子性。
在有數(shù)量限制的業(yè)務(wù)中(即先查詢(xún)的就是這個(gè)數(shù)據(jù)),要想提高成功率,可以在第二步中數(shù)據(jù)不必等于第一步查詢(xún)的數(shù)據(jù),而是小于第一步中查詢(xún)的數(shù)據(jù)即可,這樣就可以完美降低失敗率,只有數(shù)量耗盡時(shí)才會(huì)失敗。
**舉個(gè)例子:**比如賣(mài)書(shū),書(shū)有數(shù)量限制num_total=10,以賣(mài)出數(shù)量為num:
第一步查詢(xún):select * from book where id = xxx;
if (book.num < book.num_total) {可以繼續(xù)執(zhí)行第二步} else {拒絕賣(mài)書(shū)操作}
第二步查詢(xún)加更新:update book set num = num + 1 where num < num_total;
第二步中沒(méi)有使用標(biāo)準(zhǔn)的樂(lè)觀鎖即數(shù)據(jù)沒(méi)有被操作才更新 (num = #{num})
而是讓num < num_total只要沒(méi)有達(dá)到庫(kù)存上限即可操作,提高了并發(fā)的成功率,只要不是num=num_total都可以成功。
典型查詢(xún)、判斷、更新三個(gè)操作非原子性
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-717919.html
解決方案-加鎖即可,加鎖的思想分為兩類(lèi):悲觀鎖和樂(lè)觀鎖。
悲觀鎖是在操作數(shù)據(jù)之前先獲取鎖,有鎖才能操作,這樣安全了,但是性能下降了,把并發(fā)改為了單線(xiàn)程串行執(zhí)行。
樂(lè)觀鎖不加鎖,只會(huì)先查詢(xún)一次,然后在操作數(shù)據(jù)時(shí)再查詢(xún)一次(這里的查詢(xún)與修改是原子性的,例如前面第一次查詢(xún)變量a為1,等到操作數(shù)據(jù)時(shí)就要在SQL中update xxx set xxx=xxx where a = 1,這樣就讓查詢(xún)和修改操作具有原子性),如果數(shù)據(jù)改變了就異常或者重試。
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-717919.html
到了這里,關(guān)于并發(fā)安全問(wèn)題之超賣(mài)問(wèn)題的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!