简体   繁体   English

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

[英]How to do transaction operation for a number of mysql queries in node js using promise?

I have 27 mysql update queries on a single table. 我在一个表上有27个mysql更新查询。 All these queries are to be run in a transaction mode, like if one operation fails all other updated queries should rollback. 所有这些查询都将以事务模式运行,就像一个操作失败一样,所有其他更新的查询都应该回滚。

How I will implement this nodejs with promises? 我将如何使用promises实现这个nodejs?

I'm assuming you use mysql driver found here . 我假设您使用此处找到的mysql驱动程序。

According to documentation , this drivers natively supports transactions like this (copied from 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!');
      });
    });
  });
});

Since you mentioned promises, you would want to use promise-mysql package which wraps mysql calls in Bluebird promises. 既然你提到了promises,你会想要使用promise-mysql包,它在Bluebird的承诺中包含了mysql调用。

You can use below approach to handle your secnario. 您可以使用以下方法来处理您的secnario。

  • Create an array of queries which needs to be run. 创建需要运行的查询数组。 In below example I have created queries and their placeholder values and passed them as an array of objects 在下面的示例中,我创建了查询及其占位符值,并将它们作为对象数组传递
  • return a promise to caller which gets resolved when all queries supposed to be run inside a transaction finished 返回一个对调用者的承诺,当所有在事务内部运行的查询完成时,它会被解析
  • start the transaction 开始交易
  • run queries one by one inside transaction block 在事务块中逐个运行查询
  • store the result inside an accumulator as soon as query returns result 一旦查询返回结果,就将结果存储在累加器中
  • if all transactions are complete the commit the transaction and return accumulated result to caller 如果所有事务都完成,则提交事务并将累积结果返回给调用者
  • otherwise rollback the transaction and return the error to caller via promise 否则回滚事务并通过promise将错误返回给调用者

Below is the approach which I have mentioned - 以下是我提到的方法 -

 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) } } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM