我一直在尝试使用查询进行交易;我是这样做的,首先我检查并执行一个查询来检查用户是否有足够的余额,其次我扣除他的余额并处理交易。
问题是,如果你下载一个工具,或者使用一个每秒点击 200 次的宏(我认为),信号发送的速度比查询可以处理的速度快,因此它仍然会认为用户有足够的余额,这然后他最终就没有了,他的余额将变为负数。
这是快速代码
var processTransaction = function(userid, cost){
database.query('SELECT `balance` FROM `user` WHERE `id` = ' + database.pool.escape(userid), function(err, row){
if(err){
return;
}
if(!row.length){
return;
}
var userBalance = row[0].balance;
if(userBalance >= cost){
/* User has enough, process */
addBalance(userid, -cost); //deduct query
}
});
}
我在这里犯了什么错误吗?我是否有不同的处理方法?
查询功能
var query = function(sql, callback) {
if (typeof callback === 'undefined') {
callback = function() {};
}
pool.getConnection(function(err, connection) {
if(err) return callback(err);
connection.query(sql, function(err, rows) {
if(err) return callback(err);
connection.release();
return callback(null, rows);
});
});
};
最佳答案
您需要确保数据库处于一致的状态。您可以通过多种方式执行此操作,其中最简单的是:
- 使用
LOCK TABLE user WRITE
来阻止访问用户表(完成后立即解锁表)。如果您点击 200 次,不用担心 - 所有点击都将排队并且无法同时运行。
这来自the manual :
The correct way to use LOCK TABLES and UNLOCK TABLES with transactional tables, such as InnoDB tables, is to begin a transaction with SET autocommit = 0 (not START TRANSACTION) followed by LOCK TABLES, and to not call UNLOCK TABLES until you commit the transaction explicitly. For example, if you need to write to table t1 and read from table t2, you can do this:
SET autocommit=0; LOCK TABLES t1 WRITE, t2 READ, ...; ... do something with tables t1 and t2 here ... COMMIT; UNLOCK TABLES;
When you call LOCK TABLES, InnoDB internally takes its own table lock, and MySQL takes its own table lock. InnoDB releases its internal table lock at the next commit, but for MySQL to release its table lock, you have to call UNLOCK TABLES. You should not have autocommit = 1, because then InnoDB releases its internal table lock immediately after the call of LOCK TABLES, and deadlocks can very easily happen. InnoDB does not acquire the internal table lock at all if autocommit = 1, to help old applications avoid unnecessary deadlocks.
关于javascript - 人们违反了我的查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52084691/