recherche

Maison  >  Questions et réponses  >  le corps du texte

nodejs单进程产生的数据库连接多线程并发问题探讨

举例,假设有100个请求node服务器,每个请求会执行一次查询,修改数据库操作。假设10个请求按顺序被node接收处理 等待各自判定库存查询数据库io操作,但是库存只有5个,问题来了,这时候10个查询都判定库存还有,然后继续下面的下单操作。当100个请求甚至更多时,问题会被更加放大 又不能同步加锁,哪位朋友有比较合理的思路 不吝赐教~

高洛峰高洛峰2949 Il y a quelques jours904

répondre à tous(1)je répondrai

  • 高洛峰

    高洛峰2016-11-01 10:27:20

    你这种情况应该加上事务

    ----- 更新下答案 -----

    查询和实际数据不一致的问题是无法避免的,我的理解题主的意思应该是在更新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 下运行通过。。

    répondre
    0
  • Annulerrépondre