简体   繁体   English

如何在 NodeJS (expressJS) 中暂停 MySQL 数据库事务?

[英]How to pause a MySQL database transaction in NodeJS (expressJS)?

So I was given a coding challenge where a long database transaction has been initiated by a user (say a database update of some 2 million entries), but say the user accidently updates 20 million entries (maybe he took all entries from Jan 2017 to Jan 2019 when he was supposed to take entries from Jan 2018 to June 2018), so the user has initiated a transaction that takes a lot of time in the database.所以我遇到了一个编码挑战,其中一个用户发起了一个长数据库事务(比如大约 200 万个条目的数据库更新),但是说用户不小心更新了 2000 万个条目(也许他从 2017 年 1 月到 1 月2019 年,当时他应该从 2018 年 1 月到 2018 年 6 月获取条目),因此用户发起了一个在数据库中花费大量时间的事务。 The challenge is to implement a feature to allow the user to pause, cancel or resume the update.挑战在于实现一项功能以允许用户暂停、取消或恢复更新。 I have attached the code I have as of now in my server.js file.我已经在我的 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 */
}

I have used event emitters named 'pause', 'cancel' and 'resume' in the REST API end point, which will be raised everytime those requests are made by the user.我在 REST API 端点中使用了名为“pause”、“cancel”和“resume”的事件发射器,每次用户发出这些请求时都会引发这些事件发射器。 I guess the cancel logic is pretty straightforward, as there I just have to rollback and close the connection, but I am struggling with the pause and resume feature.我想取消逻辑非常简单,因为我只需要回滚并关闭连接,但我正在为暂停和恢复功能而苦苦挣扎。 How would you pause a database transaction?您将如何暂停数据库事务? And then also have the option of resuming from where you paused?然后还可以选择从暂停的地方恢复?

PS: Are there any better approaches to solve the problem? PS:有没有更好的方法来解决这个问题?

While I am not sure that this is the best answer, you could try the following:虽然我不确定这是最好的答案,但您可以尝试以下操作:

  1. Turn off autocommit关闭自动提交
  2. Start the transaction开始交易
  3. Instead of running a conditional update with a date range, you could try running an update based on id.您可以尝试根据 id 运行更新,而不是使用日期范围运行条件更新。 That way you can monitor what item you updated, by maybe storing them in a list这样你就可以监控你更新的项目,也许将它们存储在一个列表中
  4. Query your server for the status of your transaction (in progress, completed etc)查询您的服务器以了解您的交易状态(进行中、已完成等)
  5. If you want to pause the transaction, just stop running update for a while (maybe using a boolean flag)如果您想暂停事务,只需停止运行更新一段时间(可能使用布尔标志)
  6. If you want to abort the transaction, simply send the ROLLBACK command如果您想中止交易,只需发送 ROLLBACK 命令
  7. Once you're happy with your transaction, COMMIT it.一旦你对你的交易感到满意,就提交它。

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

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