处理Node.js中的回滚MySQL事务

Ada*_*dam 9 javascript mysql node.js express sequelize.js

我正在处理一个问题几天,我真的很希望,你可以帮助我.

它是一个用于的node.js基础API .sequelizeMySQL

在某些API调用中,代码启动SQL锁定某些表的事务,如果我同时向API发送多个请求,则会LOCK_WAIT_TIMEOUT出现错误.

var SQLProcess = function () {
    var self = this;
    var _arguments = arguments;

    return sequelize.transaction(function (transaction) {
            return doSomething({transaction: transactioin});
        })
        .catch(function (error) {
            if (error && error.original && error.original.code === 'ER_LOCK_WAIT_TIMEOUT') {

                return Promise.delay(Math.random() * 1000)
                    .then(function () {
                        return SQLProcess.apply(self, _arguments);
                    });

            } else {
                throw error;
            }
        });
};
Run Code Online (Sandbox Code Playgroud)

我的问题是,同时运行的请求相互锁定了很长时间,我的请求在很长一段时间后(~60秒)返回.

我希望我能解释清楚易懂,你可以给我一些解决方案.

Pet*_*ter 3

这可能不是您问题的直接答案,但也许了解一下您遇到此问题的原因也会有所帮助。

1) doSomething() 做了什么?无论如何,我们可以在那里做一些改进吗?

首先,耗时 60 秒的事务是可疑的。如果您将表锁定那么长时间,则很可能应该重新审视设计。假设典型的数据库操作运行 10 - 100 毫秒。

理想情况下,所有数据准备都应该在事务之外完成,包括从数据库读取的数据。并且事务实际上应该只用于事务性操作。

2)是否可以使用mysql存储过程?

确实,mysql 的存储过程没有像 Oracle 的 PL/SQL 那样进行编译。但它仍然在数据库服务器上运行。如果您的应用程序非常复杂,并且在该事务中数据库和节点应用程序之间包含大量反向和强制网络流量,并且考虑到有如此多的 JavaScript 调用层,那么它确实会减慢速度。如果 1) 不能节省你很多时间,请考虑使用 mysql 存储过程。

显然,这种方法的缺点是在nodejs和mysql中都很难维护代码。

如果1)和2)肯定不可能,你可以考虑某种流量控制或排队工具。要么您的应用程序确保第二个请求在第一个请求完成之前不会执行,要么您有一些第三方排队工具来处理该请求。无论如何,您似乎不需要任何并行性来运行这些请求。