node.js - nodejs單進(jìn)程產(chǎn)生的數(shù)據(jù)庫連接多線程并發(fā)問題探討
問題描述
舉例,假設(shè)有100個(gè)請求node服務(wù)器,每個(gè)請求會(huì)執(zhí)行一次查詢,修改數(shù)據(jù)庫操作。假設(shè)10個(gè)請求按順序被node接收處理 等待各自判定庫存查詢數(shù)據(jù)庫io操作,但是庫存只有5個(gè),問題來了,這時(shí)候10個(gè)查詢都判定庫存還有,然后繼續(xù)下面的下單操作。當(dāng)100個(gè)請求甚至更多時(shí),問題會(huì)被更加放大 又不能同步加鎖,哪位朋友有比較合理的思路 不吝賜教~
問題解答
回答1:站內(nèi)搜“搶購”https://segmentfault.com/sear...
極端情況為“秒殺”https://segmentfault.com/sear...
回答2:你這種情況應(yīng)該加上事務(wù)
----- 更新下答案 -----
查詢和實(shí)際數(shù)據(jù)不一致的問題是無法避免的,我的理解題主的意思應(yīng)該是在更新callback之前有其他用戶購買成功的情況會(huì)導(dǎo)致購買失敗的問題,因此可以通過加鎖解決,其實(shí)如果異步操作都使用 promise 的情況下,可以通過Promise 模擬順序調(diào)用來實(shí)現(xiàn)類似java方法加鎖的特性
通過 decorator 對返回 promise 的方法實(shí)現(xiàn)類似java synchronized 關(guān)鍵字的同步調(diào)用
// decoratorlet pfunction sync(target, name) { const method = target[name] target[name] = function(...args) { if (p) { p = p.then(() => method.apply(target, args)) } else { p = method.apply(target, args) } return p }}class Model { constructor () { // super() this._cardCount = 5 sync(this, ’buyOneCard’) } // @sync // 注解需要編譯,暫時(shí)手動(dòng)調(diào)用下 buyOneCard (user) { console.log(’buyonecard’, this._cardCount) return new Promise((resolve, reject) => { setTimeout(() => {this._cardCount = --this._cardCount this._cardCount < 0 ? reject(this._cardCount) : resolve(this._cardCount) }, 100) }) }}const m = new Model()for(let i=0;i<10;i++) m.buyOneCard().then(c => console.log(c))
chrome 下運(yùn)行通過。。
----- 再更新 ----
github 上已經(jīng)有類似工具h(yuǎn)ttps://github.com/sindresorh...
回答3:謝謝樓上兩位,首先我描述的場景是正常商品銷售,如果是搶購倒好辦 直接用redis隊(duì)列可以解決,但是商品種類多的時(shí)候 這種方式不可取。
回復(fù)樓上,這里面事務(wù)是肯定有的,但是事務(wù)并不能解決這種并發(fā)超賣的情景。 最后,如果這是用java可以很方便用隊(duì)列或同步鎖解決,但是node并不適用以上場景,redis也只能解決搶購,誰有還有合適的方案 ,期待中~回答4:
事務(wù) + 條件更新 從設(shè)計(jì)上避免了超賣。
相關(guān)文章:
1. golang - 用IDE看docker源碼時(shí)的小問題2. docker api 開發(fā)的端口怎么獲取?3. 在windows下安裝docker Toolbox 啟動(dòng)Docker Quickstart Terminal 失敗!4. docker容器呢SSH為什么連不通呢?5. docker - 各位電腦上有多少個(gè)容器啊?容器一多,自己都搞混了,咋辦呢?6. docker網(wǎng)絡(luò)端口映射,沒有方便點(diǎn)的操作方法么?7. html5 - 百度Ueditor代碼高亮和代碼段滾動(dòng)條沖突是怎么回事?8. eclipse - 如何解決no atk-wrapper in java.library.path9. javascript - vue2.0中使用vue2-dropzone的demo,vue2-dropzone的github網(wǎng)址是什么??百度不到。10. angular.js - react的redux和vue的vuex,angular呢
