【问题标题】:sequelize continue transaction after loop循环后继续交易
【发布时间】:2018-01-05 15:20:49
【问题描述】:

我在事务链代码中有多个循环,但在循环完成后事务立即提交链而不继续下一个查询。我的代码是这样的:

        return sm.sequelize.transaction(function (t) { 
          return Room.create({
            room_type: req.body.room_type
            },{transaction: t}).then(function(roomtype){
           for (i=0;i<room.length;i++){ 
               return Roomtype.create({
                   name : req.body.roomtype[i]
                    },{transaction: t}); //my transaction only work untill here and commit after that
           }
           for  (i=0;i<another.length;i++){ //I need to continue my query to second loop here
               return User.create({  
                 email :req.body.email[i]
               },{transaction:t}); 
          }
        }).then(function(result){
        }).catch (function(err){
        })
     }) 

那么如何让循环后的交易进入下一个循环呢?

【问题讨论】:

    标签: javascript express transactions sequelize.js


    【解决方案1】:

    请记住,一旦您使用return 语句,函数就结束了。您的for 循环将不再运行,第二个循环也不会运行。您需要这样做,而不是在循环中间返回。


    只要事务顺序不重要,最好的方法是使用Promise.all,它接受一组承诺,并在完成后返回所有承诺的结果。保留上面的其余逻辑,它看起来像这样:

    return Room.create({ 
      room_type: req.body.room_type 
    }, { transaction: t })
      .then(function (roomtype) {
        const promises = []
    
        for (let i = 0; i < room.length; i++) { 
          const promise = Roomtype.create({
            name : req.body.roomtype[i]
          }, { transaction: t })
          promises.push(promise)
        }
    
        for (let i = 0; i < another.length; i++){
          const promise = User.create({  
            email :req.body.email[i]
          }, { transaction: t })
          promises.push(promise)
        }
    
        return Promise.all(promises)
      })
      .then(function (results) {
        . . .
      })
    

    不过,我会更进一步,将 for 循环替换为 map。这不是绝对必要的,但会大量清理您的代码:

    return Room.create({ room_type: req.body.room_type }, { transaction: t })
      .then(function (roomtype) {
        return Promise.all(req.body.roomtype.map(function (type) {
          return Roomtype.create({ name: type }, { transaction: t })
        }))
      })
      .then(function (roomResults) {
        // Do the same thing for creating users here
      })
    

    或者,如果顺序 很重要,您可能必须执行类似递归函数的操作,该函数将按顺序遍历每个 Promise。

    const createRooms = function (transaction, types, index = 0) {
      return Roomtype.create({ name: types[index] }, { transaction })
        .then(function (result) {
          if (index < types.length - 1) {
            return createRooms(transaction, types, index + 1)
          }
          return result
        })
    }
    

    然后您将在代码中调用该函数:

    return Room.create({ room_type: req.body.room_type }, { transaction: t })
      .then(function (roomtype) {
        return createRooms(t, req.body.roomtype)
      })
      .then(function (result) {
        // Do the same thing for creating Users here
      })
    

    【讨论】:

      猜你喜欢
      • 2020-02-23
      • 1970-01-01
      • 1970-01-01
      • 2011-08-19
      • 2020-07-01
      • 2017-11-21
      • 2018-03-20
      相关资源
      最近更新 更多