javascript - 当发生写入数据库的并发 API 调用时(或者当服务器速度缓慢时),防止竞争情况

标签 javascript node.js postgresql asynchronous upsert

让我们想象一个场景,您将有一个端点用于创建用户。这将发生在一个 Restful 应用程序中,所以让我们想象一下,一个富客户端调用这个 API 端点。

exports.createUser = function(req,res){
    if(req.body){
        //Check if email has already been used
        db.User.find({where:{email:req.body.email}}).success(function(user){
            if(user === null || user === undefined){
                //Create user
                res.send(201);
            } else {
                res.json(409,{error: 'User already exists'});
            }
        });
    } else {
        res.send(400);
    }
};

如果我非常快地多次调用此端点,则可以在数据库中使用同一电子邮件创建多个记录,即使您查询用户表以确保不会出现重复也是如此。

我确信这是一个常见问题,但是如何防止这个问题呢?我严格限制对某些端点的请求数量,但这似乎不是一个很好的解决方案。

有什么想法吗? 非常感谢!

最佳答案

最简单的选择是在执行查找然后插入的事务开始时以独占模式锁定表“用户”。这确保一次只能有一个事务写入表。

为了获得更好的并发性,您可以:

如果使用唯一约束,需要考虑的一件事是您的应用可能会将用户标记为禁用而不删除它们,并且可能不希望强制禁用用户的电子邮件地址是唯一的。如果是这样,您可能需要部分唯一索引(请参阅文档)。

关于javascript - 当发生写入数据库的并发 API 调用时(或者当服务器速度缓慢时),防止竞争情况,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25296929/

相关文章:

javascript - 如何使用 `if` 条件和分隔符拆分字符串

javascript - 如何使用 d3 重新启动(恢复) Canvas 动画中暂停的计时器

javascript - Angular - Node Express - 大图像上传问题

PostgreSQL意外删除用户postgres

javascript - 如何处理/解析/读取 "multipart/mixed; boundary=batch"响应

javascript - 如果拖放子节点如何获取父节点的文本?

Javascript - 使函数异步

node.js - 如何将 Node Js、Express 和 Mongo DB 应用程序部署到 Windows Server 2012 R2

ruby-on-rails - Rails 5 + postgresql 多个字段的表引用关系

sql - PostgreSQL 错误 : syntax error at or near "varchar"