2012-07-25 69 views
4

我不是在谈论真金白银交易是否有可能使用node.js和noSQL db进行事务处理?

我工作的这个项目是一个游戏,玩家之间相互交易的东西。这基本上是一个交易过程,玩家A给了玩家B 10粒去交换30头奶牛,你明白了。

但是因为它是互动的,并且有很多玩家同时在类似聊天室的环境中进行随机交易,我想知道是否有可能通过node.js来做这样的事情,但我看到了问题。

我来自数据库背景,其中处理交易和rollbackcommit的性质是必要的,以维护数据库的健康状态。但如果我们谈论node.jsmongoDB(或任何其他的noSQL DB),这肯定是一个完全不同的思路,但我不明白它是如何处理交易的,因为只有两方应该参与而不诉诸某种形式的锁定,但肯定不是什么node

我还没有找到任何东西,但这并不令我感到意外,因为node.js太新颖了。

UPDATE我意识到交易的机制 - 特别是银行风格的交易,但这不是同一回事。我可能没有说清楚,但问题是,玩家B正在向买家群体推销某些东西。

这意味着虽然玩家A在客户端发起购买指令,但也有可能大约在同一时间玩家C D或E也点击购买相同的牛。

现在在正常的交易中,预计至少第一个获得记录级别表的人至少阻止其他方在该时间点继续进行。

然而,节点的使用性质,特别是其速度,并发处理和显示实时更新数据库的使用意味着我可以轻易想象,最慢的人(我们正在说毫秒)获胜。

例如玩家A在与玩家C同时发起购买。玩家交易完成并且将银币支付给玩家B,并且将牛分配给数据库上的玩家A.一毫秒后牛被分配给玩家C.

我希望能更好地解释这个问题。

回答

4

这与Node.JS无关。 Node.JS只连接到数据库,事务由数据库本身完成(除非你想在Node.JS中手动实现事务,这可能有点困难 - 但任何语言编写的任何Web服务器都是如此)。

你可以很容易地使用MySQL(例如)支持事务的Node.JS。所以你问的问题是:我可以使用MongoDB进行交易吗?答案是:不,是。

不,因为MongoDB不支持开箱即用的交易。

是的,因为您可以使用一些技巧来模拟交易。例如参见this article

1

要使用文档数据库进行银行业务式交易,通常使用事务日志模式。在这种模式下,您可以将每个交易写为自己的凭证。您不保留与每个账户余额相对应的文件。相反,您在查询时上传交易文件,以提供当前余额。

下面是适用于Couchbase地图缩小的例子:http://guide.couchdb.org/draft/recipes.html

2

我工作的OSS应用程序级的事务数据库上的node.js称为Waterline

我们从全增长的CRUD开始,但很快就意识到这很难。最好把它留给数据库。但有时你不想 - 因为你希望能够切换数据库并保持你的代码不可知。那么我们简化到下一个最简单的命名交易。

因此,没有内置回滚支持(您现在仍然必须自己做),但至少Waterline会阻止您同时访问。

在您的例子(假设你在快递是/连接/ Sails)它可能看起来像:

function buyCow (req,res) { 
    Cow.find(req.param('cowId'),function (err,cow) { 
     if (err) return req.send(500,err); 

     Cow.transaction('buy_cow',function (err, unlock) { 
     if (err) { 
      // Notice how I unlock before each exit point? REALLY important. 
      // (would love to hear thoughts on an easier way to do this) 
      unlock(); 
      return res.send(500,err); 
     } 

     User.find(req.session.userId,function (err,user) { 
      // If there's not enough cash, send an error 
      if (user.money - cow.price < 0) { 
       unlock(); 
       return res.send(500,'Not enough cash!'); 
      } 

      // Update the user's bank account 
      User.update(user.id,{ 
       money: user.money - cow.price 
      }, function (err,user) { 
       if (err) { unlock(); return res.send(500,err); } 

       Cow.update(cow.id, {owner: user.id}, function (err, cow) { 
        if (err) { unlock(); return res.send(500,err); } 

        // Success! 
        unlock(); 
        res.json({success: true}); 
       }); 

      }); 
     }); 
     }); 

    }); 
} 

希望有所帮助。我欢迎您的反馈意见(也许是提交?)

+0

这可能很有意思,但我们已经采取了另一种方式来推进项目,因为发布该问题后对此主题知之甚少。 – T9b 2012-12-30 13:46:17

+0

有道理 - 那么,如果你想查看它,我昨晚完成了第一个水线的发布:http://github.com/mikermcneil/waterline 它设置为使用dirtydb,一个内存数据库。我的下一步是创建一个mongodb适配器,然后创建mySQL(mySQL适配器将使用mySQL的内置事务) – mikermcneil 2012-12-30 23:46:25

相关问题