简体   繁体   中英

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

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. 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?

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. 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
  7. Once you're happy with your transaction, COMMIT it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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