Is it possible to process transactions using node.js and noSQL db?

I'm not talking about real money transactions

The project I'm working on is a game in which players trade with each other. This is basically a transaction process, player A gives player B 10 cereals in exchange for thirty cows, you get the idea.

But since it is interactive, and there are many players at the same time, in a chat-like environment, all the random trading operations I wondered if this thing could be done with node.js , but I see problems.

I come from a database of databases where transaction processing and the nature of rollback and commit necessary to maintain the state of the database. But if we say node.js plus mongoDB (or any other noSQL database), then this is definitely a completely different mentality, but I just don’t see how it can handle trade in the sense that only two parties should be involved. without resorting to any form of locking, but, of course, not about what node about.

I have not found anything yet, but it does not surprise me, because node.js is so new.

UPDATE . I know the mechanisms of a transaction - and in particular banking style transactions, but they are not the same thing. Perhaps I did not make it clear, but the problem is that player B is selling something to the community of buyers.

This means that although player A initiates the purchase instruction on the client side, it is also possible that around the same time, player CD or E also clicks to buy the same cow.

Now, in a normal transaction, it is expected that at least the first person who gets a lock on the record level table will at least block the other parties from what is happening at that point in time.

However, the nature of node use and, in particular, its speed, parallel processing and use to display the database of updates in real time means that I could easily imagine that the slowest person wins (we say milliseconds).

For example, player A initiates a purchase at the same time as player C. The player completes the transaction, and Grottoes are paid to player B, and a cow is assigned to player A in the database. After a millisecond, the cow is assigned to player C.

I hope this explains the problem better.

+4
source share
3 answers

This has nothing to do with Node.JS. Node.JS only connects to the database, and the transactions are carried out by the database itself (if you do not want to manually execute transactions in Node.JS, which can be a bit of a challenge - but this is the same for any web server written in any language )

You can easily use (for example) MySQL with Node.JS, which supports transactions. So you ask the question: can I do transactions with MongoDB? The answer is no and yes.

No, since MongoDB does not support out-of-box transactions.

Yes, because you can use some tricks to emulate transactions. See, for example, in this article .

+4
source

I am working on an oss application-level transactional database for node.js called Waterline .

We started with full-blown CRUD mutations, but soon realized that it was rather complicated. It is better to leave this in the database. But sometimes you don’t want to ... because you want to be able to switch between databases and keep your code agnostic. So, we have simplified to the next simple part - named transactions.

So, rollback support is not built-in (you still have to do it yourself), but at least Waterline prevents concurrent access for you.

In your example (if you are in the / connect / Sails expression), it might look something like this:

 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 not enough cash, send an error if (user.money - cow.price < 0) { unlock(); return res.send(500,'Not enough cash!'); } // Update the user 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}); }); }); }); }); }); } 

Hope this helps. I welcome your feedback (and perhaps commit?)

+2
source

For bank-style transactions with a document database, it is typical to use a transaction log template. In this template, you must write each transaction as its own document. Documents corresponding to each account balance are not supported. Instead, you roll up transaction documents at the time of the request to give current balance (s).

Here is an example applicable to reducing the Couchbase map: http://guide.couchdb.org/draft/recipes.html

+1
source

All Articles