如何使用promise对节点js中的许多mysql查询进行事务操作?

时间:2017-05-11 07:08:26

标签: mysql node.js bluebird

我在一个表上有27个mysql更新查询。所有这些查询都将以事务模式运行,就像一个操作失败一样,所有其他更新的查询都应该回滚。

我将如何使用promises实现此nodejs?

2 个答案:

答案 0 :(得分:0)

我假设你使用mysql驱动程序here

根据documentation,这些驱动程序原生支持这样的事务(从文档中复制):

connection.beginTransaction(function(err) {
  if (err) { throw err; }
  connection.query('INSERT INTO posts SET title=?', title, function (error, results, fields) {
    if (error) {
      return connection.rollback(function() {
        throw error;
      });
    }

    connection.query('INSERT INTO log SET data=?', log, function (error, results, fields) {
      if (error) {
        return connection.rollback(function() {
          throw error;
        });
      }
      connection.commit(function(err) {
        if (err) {
          return connection.rollback(function() {
            throw err;
          });
        }
        console.log('success!');
      });
    });
  });
});

既然你提到了promises,那么你会想要使用promise-mysql包来封装在Bluebird承诺中的mysql调用。

答案 1 :(得分:0)

您可以使用以下方法处理您的secnario。

  • 创建需要运行的查询数组。在下面的示例中,我创建了查询及其占位符值,并将它们作为对象数组传递
  • 向调用者返回一个promise,当所有查询应该在一个事务内部运行时,它将被解析
  • 开始交易
  • 在事务块
  • 中逐个运行查询
  • 一旦查询返回结果
  • ,就将结果存储在累加器中
  • 如果所有交易都完成,则提交交易并将累计结果返回给来电者
  • 否则回滚事务并通过promise
  • 将错误返回给调用者

以下是我提到的方法 -



function executeTransaction(queries) {
    try {
      const connection = yield getConnectionObj({/* your db params to get connection */)
  
      let results = []

      return new Promise(function(resolve, reject) {
        connection.beginTransaction(function (err) {
          if (err) throw err

          console.log("Starting transaction")

          queries
            .reduce(function (sequence, queryToRun) {
              return sequence.then(function () {
                parent.query(queryToRun.query, queryToRun.values)
                /* pass your query and connection to a helper function and execute query there */
                return queryConnection(
                  connection,
                  query,
                  queryParams,
                ).then(function (res) {
                  /* Accumulate resposes of all queries */
                  results = results.concat(res)
                })
              }).catch(function (error) {
                reject(error)
              })
            }, Promise.resolve())
            .then(function () {
              connection.commit(function (err) {
                if (err) {
                 /* rollback in case of any error */
                  connection.rollback(function () {
                    throw err
                  })
                }
                console.log('Transactions were completed!')
                /* release connection */
                connection.release()
                /* resolve promise with all results */
                resolve({ results })
              })
            })
            .catch(function (err) {
              console.log('Transaction failed!')
              connection.rollback(function () {
                console.log('Abort Transaction !!!')
                throw err
              })
            })
        })
      })
   /* End Transaction */

    } catch (error) {
      return Promise.reject(error)
    }
  }