Node.js mysql事务

Ale*_*ace 10 mysql transactions node.js express node-mysql

任何人都可以提供一个如何在Node.js中实现MySQL事务的示例.我试图使用node-mysql驱动程序和node-mysql-queue来解决问题.

据我所知,使用node-mysql-queue会大大降低Node.js的异步性质,因为新查询必须等到现有的查询完成.为了解决这个问题,有人试图将node-mysql-queue与node-mysql的连接池功能结合起来.即为每个新的http请求启动一个新的mysql连接,并在各个连接上启动事务队列?

She*_*tJS 14

一个月前,文档中添加了以下事务示例:

https://github.com/felixge/node-mysql#transactions

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

    var log = 'Post ' + result.insertId + ' added';

    connection.query('INSERT INTO log SET data=?', log, function(err, result) {
      if (err) { 
        connection.rollback(function() {
          throw err;
        });
      }  
      connection.commit(function(err) {
        if (err) { 
          connection.rollback(function() {
            throw err;
          });
        }
        console.log('success!');
      });
    });
  });
});
Run Code Online (Sandbox Code Playgroud)

  • 这并没有真正解决异步问题.在事务完成之前,connect应该专门用于事务. (6认同)

Dan*_*ing 10

我花了一些时间编写节点mysql给出的事务示例的通用版本,所以我想我会在这里分享它.我使用Bluebird作为我的promise库,并用它来'promisify'连接对象,这简化了异步逻辑.

const Promise = ('bluebird');
const mysql = ('mysql');

/**
 * Run multiple queries on the database using a transaction. A list of SQL queries
 * should be provided, along with a list of values to inject into the queries.
 * @param  {array} queries     An array of mysql queries. These can contain `?`s
 *                              which will be replaced with values in `queryValues`.
 * @param  {array} queryValues An array of arrays that is the same length as `queries`.
 *                              Each array in `queryValues` should contain values to
 *                              replace the `?`s in the corresponding query in `queries`.
 *                              If a query has no `?`s, an empty array should be provided.
 * @return {Promise}           A Promise that is fulfilled with an array of the
 *                              results of the passed in queries. The results in the
 *                              returned array are at respective positions to the
 *                              provided queries.
 */
function transaction(queries, queryValues) {
    const connection = mysql.createConnection(databaseConfigs);
    Promise.promisifyAll(connection);
    return connection.connectAsync()
    .then(connection.beginTransactionAsync())
    .then(() => {
        const queryPromises = [];

        queries.forEach((query, index) => {
            queryPromises.push(connection.queryAsync(query, queryValues[index]));
        });
        return Promise.all(queryPromises);
    })
    .then(results => {
        return connection.commitAsync()
        .then(connection.endAsync())
        .then(() => {
            return results;
        });
    })
    .catch(err => {
        return connection.rollbackAsync()
        .then(connection.endAsync())
        .then(() => {
            return Promise.reject(err);
        });
    });
}
Run Code Online (Sandbox Code Playgroud)

如果您想按照问题中的建议使用池,则可以轻松切换createConnection线myPool.getConnection(...),并使用切换connection.end线connection.release().