假设我有某种游戏。我有一个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.busy将undefined在第一〜5项要求。因此,这也不起作用。
req.session.user.busy
undefined
我们如何处理这种情况?如果重要的话,我正在使用Sails.JS框架。
更新2 通过该方法,Sails 1.0现在具有完整的事务支持.getDatastore()。例:
通过该方法,Sails 1.0现在具有完整的事务支持.getDatastore()。例:
.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)。
正如一些评论者所指出的,启用连接池时,以下代码不起作用。在这个最初发布的时候,并不是所有的适配器汇集默认,但在这一点上应该假定他们这样做,让每一个人的方法调用(.query(),.findOne(),等)可以在不同的连接,在交易之外进行操作。Waterline的下一个主要版本将提供事务支持,但是在那之前,确保您的查询具有事务性的唯一方法是使用原始数据库驱动程序包(例如pg或mysql)。
.query()
.findOne()
听起来您需要一笔交易。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); }); } }