I am having a problem with NodeJS. When I am trying to post/update
One balance
One account
Two different users
at the same time.
Example:
I have API with ExpressJS for post data to the t_account
table like this.
I need to get latest balance first from max(id)
after each transaction.
I'm trying to get balance of 400 NOT
300
For Example:
Code Example:
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",
})
}})
The problem is when two user post data in the same time, I get the incorrect balance.
Code Example of Initializing my Transactions:
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
Console Logs
The last balance not right showing 300 instead of 400.
What is going wrong here?
You need to lock the row that you are reading so that you can update this row before anyone else can read it. Look at innodb-locking-reads , specifically for update
From docs
Locking of rows for update using SELECT FOR UPDATE only applies when autocommit is disabled (either by beginning transaction with START TRANSACTION or by setting autocommit to 0. If autocommit is enabled, the rows matching the specification are not locked.
Going off of your provided info, and not knowing more about NodeJS or your OS, Versions, setup etc. This is my thought process as what each issue I see.
As silly as this may actually be, there are so many unknown factors.
After that is out of the way check:
saveBalance',async function
Maybe the cause of the double SELECT...SELECT
double INSERT...INSERT
If the saveBalance',async function
is fine. I would check your Database settings
as based on your MySQL Console Logs & that you are using localhost
This Might be due to an issue with your MySQL Database Settings.
SQL Code:
SELECT @@GLOBAL.TX_ISOLATION;
It also, might interest you to use START TRANSACTIONS;
But be sure to enable multistatements in your config. and this is also directly tied to the TX_ISOLATION
as well.
My example would modify your Query like so:
let SQL2="START TRANSACTION; INSERT INTO t_account(no,balance) VALUES('"+req.body.no+"',"+newBalance+"); COMMIT;";
Lastly, I also recommend reading 'Approach to multiple MySQL queries with Node.js - One should avoid the pyramid of doom'
I hope this helps.
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.