我在一个表上有27个mysql更新查询。所有这些查询都将以事务模式运行,就像一个操作失败一样,所有其他更新的查询都应该回滚。
我将如何使用promises实现此nodejs?
答案 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。
以下是我提到的方法 -
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)
}
}