javascript - 人们违反了我的查询

标签 javascript mysql node.js

我一直在尝试使用查询进行交易;我是这样做的,首先我检查并执行一个查询来检查用户是否有足够的余额,其次我扣除他的余额并处理交易。

问题是,如果你下载一个工具,或者使用一个每秒点击 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/

相关文章:

javascript - 检测 Mongoose 事件的语法是什么?

javascript - 选择器在 jquery 中不起作用

javascript - 获得readyState为4和status为200加上statusText为 "OK"并且success函数仍然没有被调用

mysql - Node.js - 获取所有已连接客户端 IP 地址的列表?

mysql - Google Cloud SQL 卡在重启时

javascript - npx create-next-app@latest --ts 3 个高严重性漏洞 [node-fetch 容易受到向未经授权的参与者泄露敏感信息的影响]

javascript - Angular 2+ 中的悬停意图实现

javascript - JQuery - 随机 .replace() 错误

mysql加入: Where to put the condition that goes on the right table?

node.js - 使用nodemailer发送电子邮件不适用于互联网服务,但适用于本地服务器