[英]NodeJS How To Handle Concurrent Request To MySQL
我在使用NodeJS时遇到问题。 当我尝试发布/更新时
One balance
One account
Two different users
帖子 at the same time.
例:
我的ExpressJS具有API,用于将数据发布到t_account
表中,如下所示。
我需要在每次交易后首先从max(id)
获取最新余额。
我正在尝试获得400 NOT
300的余额
例如:
代码示例:
router.post('/saveBalance',async function (req, res) {
try {
let SQL="SELECT balance FROM t_account WHERE id=(SELECT max(id) FROM t_account WHERE no='"+req.body.no+"')";
let queryResult=await db.myexec(SQL);
let newBalance=queryResult[0].balance+req.body.balance;
let SQL2="INSERT INTO t_account(no,balance) VALUES('"+req.body.no+"',"+newBalance+")";
let queryResult2=await db.myexec(SQL2);
res.status(200).json( {
error:"false",
code:"00",
message:"Balance Bank is saved",
})
} catch (error) {
res.status(400).json( {
error:"true",
code:"03",
message:"Balance Bank failed to saved",
})
}})
问题是当两个用户同时发布数据时,我得到了不正确的余额。
初始化我的交易的代码示例:
const axios = require('axios'); axios.post('http://localhost:3000/rbank/saveBalance/', { "no":"11", "balance":100 } ) axios.post('http://localhost:3000/rbank/saveBalance/', { "no":"11", "balance":200 } )
MySQL
控制台日志
最后一个余额显示300,而不是400。
这是怎么了?
您需要锁定正在读取的行,以便在其他任何人都可以读取它之前更新此行。 查看innodb-locking-reads ,专门for update
来自文档
使用SELECT FOR UPDATE锁定更新行仅在禁用自动提交时才适用(通过以START TRANSACTION开始事务或将autocommit设置为0。如果启用了自动提交,则不锁定与规范匹配的行。
不再提供您提供的信息,并且不了解有关NodeJS或您的操作系统,版本,设置等的更多信息。这就是我所看到的每个问题的思考过程。
尽管实际上这很愚蠢,但有许多未知因素。
之后,请检查:
saveBalance',async function
可能是双重SELECT...SELECT
双重INSERT...INSERT
如果saveBalance',async function
很好。 我会根据您的MySQL控制台日志和您正在使用localhost
来检查Database settings
这可能是由于您的MySQL数据库设置有问题。
SQL代码:
SELECT @@GLOBAL.TX_ISOLATION;
另外,您可能会喜欢使用START TRANSACTIONS;
但是请确保在配置中启用多语句。 并且这也直接与TX_ISOLATION
绑定。
我的示例将像这样修改您的查询:
let SQL2="START TRANSACTION; INSERT INTO t_account(no,balance) VALUES('"+req.body.no+"',"+newBalance+"); COMMIT;";
最后,我还建议阅读“使用Node.js到多个MySQL查询的方法-应该避免厄运金字塔”
我希望这有帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.