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)
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().