84669 orang belajar
152542 orang belajar
20005 orang belajar
5487 orang belajar
7821 orang belajar
359900 orang belajar
3350 orang belajar
180660 orang belajar
48569 orang belajar
18603 orang belajar
40936 orang belajar
1549 orang belajar
1183 orang belajar
32909 orang belajar
举例,假设有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队列可以解决,但是商品种类多的时候 这种方式不可取。
事务 + 条件更新 从设计上避免了超卖。