如何在 NodeJS (expressJS) 中暂停 MySQL 数据库事务?
How to pause a MySQL database transaction in NodeJS (expressJS)?
所以我遇到了一个编码挑战,其中一个用户发起了一个很长的数据库事务(比如数据库更新了大约 200 万条条目),但是说用户不小心更新了 2000 万条条目(也许他拿走了所有条目从 2017 年 1 月到 2019 年 1 月,当时他应该从 2018 年 1 月到 2018 年 6 月进行输入),因此用户发起了一个在数据库中花费大量时间的事务。挑战在于实现一项允许用户暂停、取消或恢复更新的功能。我已经在我的 server.js 文件中附加了我现在拥有的代码。
function getDataForDateRange(res, dateLowerBound, dateUpperBound, updateValue) {
/* Begin transaction */
connection.beginTransaction(function (err) {
console.log('Transaction will begin...')
if (err) {
console.log('ERROR: ', err);
throw err;
}
connection.query('UPDATE sakila.customer SET ? WHERE create_date >= ? AND create_date <= ?', [{ active: uVal }, dateLB, dateUB], function (err, result) {
console.log('query started.');
if (err) {
connection.rollback(function () {
console.log('ERROR, database transaction rolled back.')
throw err;
});
}
em.addListener('pause', function () {
console.log('Event Listener pause request callback called.');
// I want to wait until resume event happens
// pause the database transaction here. How do I do that?
em.addListener('resume', function () {
//connection.resume() --> find a function which can do this?
console.log('Connection resumed');
});
console.log('done waiting for resume button press');
});
//cancel event listener
em.addListener('cancel', function () {
connection.rollback(function () {
console.log('CANCELLED transaction upon user request');
console.log('transaction has been rolled back due to user cancelling transaction.');
});
});
connection.commit(function(err) {
if (err) {
connection.rollback(function() {
throw err;
});
}
console.log('successfully committed');
});
});
});
/* End transaction */
}
我在 REST API 端点使用了名为 'pause'、'cancel' 和 'resume' 的事件发射器,每次这些请求由用户。我想取消逻辑非常简单,因为我只需要回滚并关闭连接,但我正在努力使用暂停和恢复功能。您将如何暂停数据库事务?然后还可以选择从暂停的地方继续?
P.S: 有没有更好的方法解决这个问题?
虽然我不确定这是否是最佳答案,但您可以尝试以下操作:
- 关闭自动提交
- 开始交易
- 您可以尝试 运行 基于 id 的更新,而不是 运行 具有日期范围的条件更新。这样你就可以通过将它们存储在列表中来监视你更新的项目
- 查询您的服务器以了解您的交易状态(进行中、已完成等)
- 如果您想暂停交易,只需停止 运行 更新一段时间(可能使用布尔标志)
- 如果您想中止交易,只需发送 ROLLBACK 命令
- 一旦您对交易感到满意,请提交。
所以我遇到了一个编码挑战,其中一个用户发起了一个很长的数据库事务(比如数据库更新了大约 200 万条条目),但是说用户不小心更新了 2000 万条条目(也许他拿走了所有条目从 2017 年 1 月到 2019 年 1 月,当时他应该从 2018 年 1 月到 2018 年 6 月进行输入),因此用户发起了一个在数据库中花费大量时间的事务。挑战在于实现一项允许用户暂停、取消或恢复更新的功能。我已经在我的 server.js 文件中附加了我现在拥有的代码。
function getDataForDateRange(res, dateLowerBound, dateUpperBound, updateValue) {
/* Begin transaction */
connection.beginTransaction(function (err) {
console.log('Transaction will begin...')
if (err) {
console.log('ERROR: ', err);
throw err;
}
connection.query('UPDATE sakila.customer SET ? WHERE create_date >= ? AND create_date <= ?', [{ active: uVal }, dateLB, dateUB], function (err, result) {
console.log('query started.');
if (err) {
connection.rollback(function () {
console.log('ERROR, database transaction rolled back.')
throw err;
});
}
em.addListener('pause', function () {
console.log('Event Listener pause request callback called.');
// I want to wait until resume event happens
// pause the database transaction here. How do I do that?
em.addListener('resume', function () {
//connection.resume() --> find a function which can do this?
console.log('Connection resumed');
});
console.log('done waiting for resume button press');
});
//cancel event listener
em.addListener('cancel', function () {
connection.rollback(function () {
console.log('CANCELLED transaction upon user request');
console.log('transaction has been rolled back due to user cancelling transaction.');
});
});
connection.commit(function(err) {
if (err) {
connection.rollback(function() {
throw err;
});
}
console.log('successfully committed');
});
});
});
/* End transaction */
}
我在 REST API 端点使用了名为 'pause'、'cancel' 和 'resume' 的事件发射器,每次这些请求由用户。我想取消逻辑非常简单,因为我只需要回滚并关闭连接,但我正在努力使用暂停和恢复功能。您将如何暂停数据库事务?然后还可以选择从暂停的地方继续?
P.S: 有没有更好的方法解决这个问题?
虽然我不确定这是否是最佳答案,但您可以尝试以下操作:
- 关闭自动提交
- 开始交易
- 您可以尝试 运行 基于 id 的更新,而不是 运行 具有日期范围的条件更新。这样你就可以通过将它们存储在列表中来监视你更新的项目
- 查询您的服务器以了解您的交易状态(进行中、已完成等)
- 如果您想暂停交易,只需停止 运行 更新一段时间(可能使用布尔标志)
- 如果您想中止交易,只需发送 ROLLBACK 命令
- 一旦您对交易感到满意,请提交。