84669 人學習
152542 人學習
20005 人學習
5487 人學習
7821 人學習
359900 人學習
3350 人學習
180660 人學習
48569 人學習
18603 人學習
40936 人學習
1549 人學習
1183 人學習
32909 人學習
举例,假设有100个请求node服务器,每个请求会执行一次查询,修改数据库操作。假设10个请求按顺序被node接收处理 等待各自判定库存查询数据库io操作,但是库存只有5个,问题来了,这时候10个查询都判定库存还有,然后继续下面的下单操作。当100个请求甚至更多时,问题会被更加放大 又不能同步加锁,哪位朋友有比较合理的思路 不吝赐教~
走同样的路,发现不同的人生
車站內搜尋「搶購」https://segmentfault.com/sear...
極端情況為「秒殺」https://segmentfault.com/sear...
你這種情況應該加上事務
----- 更新下答案 -----
查詢和實際資料不一致的問題是無法避免的,我的理解題主的意思應該是在更新callback之前有其他用戶購買成功的情況會導致購買失敗的問題,因此可以透過加鎖解決,其實如果異步操作都使用promise 的情況下,可以透過Promise 模擬順序呼叫來實現類似java方法加鎖的特性
透過 decorator 對傳回 promise 的方法實作類似java synchronized 關鍵字的同步呼叫
// decorator let p function 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 // 注解需要编译,暂时手动调用下 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 下運行通過。 。
----- 再更新 ----
github 上已經有類似工具https://github.com/sindresorh...
謝謝樓上兩位,首先我描述的場景是正常商品銷售,如果是搶購倒好辦 直接用redis隊列可以解決,但是商品種類多的時候 這種方式不可取。
回复楼上,这里面事务是肯定有的,但是事务并不能解决这种并发超卖的情景。 最后,如果这是用java可以很方便用队列或同步锁解决,但是node并不适用以上场景,redis也只能解决抢购,谁有还有合适的方案 ,期待中~
事務 + 條件更新 從設計上避免了超賣。
車站內搜尋「搶購」
https://segmentfault.com/sear...
極端情況為「秒殺」
https://segmentfault.com/sear...
你這種情況應該加上事務
----- 更新下答案 -----
查詢和實際資料不一致的問題是無法避免的,我的理解題主的意思應該是在更新callback之前有其他用戶購買成功的情況會導致購買失敗的問題,因此可以透過加鎖解決,其實如果異步操作都使用promise 的情況下,可以透過Promise 模擬順序呼叫來實現類似java方法加鎖的特性
透過 decorator 對傳回 promise 的方法實作類似java synchronized 關鍵字的同步呼叫
chrome 下運行通過。 。
----- 再更新 ----
github 上已經有類似工具
https://github.com/sindresorh...
謝謝樓上兩位,首先我描述的場景是正常商品銷售,如果是搶購倒好辦 直接用redis隊列可以解決,但是商品種類多的時候 這種方式不可取。
事務 + 條件更新 從設計上避免了超賣。