当前位置: 首页 > 面试题库 >

如何正确处理异步并发请求?

司寇经亘
2023-03-14
问题内容

假设我有某种游戏。我有一个buyItem函数,如下所示:

buyItem: function (req, res) {
    // query the users balance
    // deduct user balance
    // buy the item
}

如果我对该路由进行垃圾邮件处理,直到扣除用户余额(第二次查询),则用户余额仍为正。

我尝试过的

buyItem: function (req, res) {
    if(req.session.user.busy) return false;
    req.session.user.busy = true;
    // query the users balance
    // deduct user balance
    // buy the item
}

问题是req.session.user.busyundefined在第一〜5项要求。因此,这也不起作用。

我们如何处理这种情况?如果重要的话,我正在使用Sails.JS框架。


问题答案:

通过该方法,Sails 1.0现在具有完整的事务支持.getDatastore()。例:

// Get a reference to the default datastore, and start a transaction.
await sails.getDatastore().transaction(async (db, proceed)=> {
  // Now that we have a connection instance in `db`, pass it to Waterline
  // methods using `.usingConnection()` to make them part of the transaction:
  await BankAccount.update({ balance: 5000 }).usingConnection(db);
  // If an error is thrown, the transaction will be rolled back.
  // Or, you can catch errors yourself and call `proceed(err)`.
  // To commit the transaction, call `proceed()`
  return proceed();
  // You can also return a result with `proceed(null, result)`.
});

更新资料

正如一些评论者所指出的,启用连接池时,以下代码不起作用。在这个最初发布的时候,并不是所有的适配器汇集默认,但在这一点上应该假定他们这样做,让每一个人的方法调用(.query().findOne(),等)可以在不同的连接,在交易之外进行操作。Waterline的下一个主要版本将提供事务支持,但是在那之前,确保您的查询具有事务性的唯一方法是使用原始数据库驱动程序包(例如pg或mysql)。

听起来您需要一笔交易。Sails尚不支持框架级别的事务(正在路线图上),但是如果您使用支持事务的数据库(例如Postgres或MySQL),则可以使用.query()模型的方法来访问基础适配器并运行本机命令。这是一个例子:

buyItem: function(req, res) {
  try {
    // Start the transaction
    User.query("BEGIN", function(err) {
      if (err) {throw new Error(err);}
      // Find the user
      User.findOne(req.param("userId").exec(function(err, user) {
        if (err) {throw new Error(err);}
        // Update the user balance
        user.balance = user.balance - req.param("itemCost");
        // Save the user
        user.save(function(err) {
          if (err) {throw new Error(err);}
          // Commit the transaction
          User.query("COMMIT", function(err) {
            if (err) {throw new Error(err);}
            // Display the updated user
            res.json(user);
          });
        });
      });
    });
  } 
  // If there are any problems, roll back the transaction
  catch(e) {
    User.query("ROLLBACK", function(err) {
      // The rollback failed--Catastrophic error!
      if (err) {return res.serverError(err);}
      // Return the error that resulted in the rollback
      return res.serverError(e);
    });
  }
}


 类似资料:
  • Spring MVC 3.2开始引入了基于Servlet 3的异步请求处理。相比以前,控制器方法已经不一定需要返回一个值,而是可以返回一个java.util.concurrent.Callable的对象,并通过Spring MVC所管理的线程来产生返回值。与此同时,Servlet容器的主线程则可以退出并释放其资源了,同时也允许容器去处理其他的请求。通过一个TaskExecutor,Spring M

  • 问题内容: 我有一个关于单例bean如何详细处理并发请求的问题。 我想要有关单例bean如何处理并发请求以及系统处理器如何看到这些请求的完整详细信息。 我已经研究了有关在线处理系统处理器中并发请求的问题。他们说处理器本身有一个调度程序,调度程序将决定处理哪个请求。 好的。如果假设我有多个核心处理器,那么调度程序如何处理并发请求? 谁能向我解释有关单例bean如何为JVM和系统中的并发请求提供服务的

  • 本文向大家介绍如果将axios异步请求同步化处理?相关面试题,主要包含被问及如果将axios异步请求同步化处理?时的应答技巧和注意事项,需要的朋友参考一下

  • 我是webflux的新手,无法找到正确的材料来继续实现。 null

  • 并发请求处理 我创建了一个服务器,并使用s.listenandserve()来处理请求。据我所知,这些请求是同时送达的。我使用一个简单的处理程序来检查它: 我看到,如果我发送了几个请求,我将看到所有的“1”出现,只有在一秒钟后所有的“2”出现。但是如果删除Hibernate行,我会看到程序在完成前一个请求之前从不启动请求(输出为1 2 1 2 1 2...)。所以我不明白,如果它们是并发的还是不是

  • 有一个场景,1000个请求要求redis获取名为goods_stock的密钥,同时在redis中设置该密钥的vaule等于goods_stocks-1,redis服务器如何处理这些请求?它是否处理默认队列,就像每个请求都是块请求一样?