5

私は実際のお金の取引について話しているのではありません

私が取り組んでいるプロジェクトは、プレイヤー同士で物を交換するゲームです。これは基本的に取引プロセスであり、プレイヤー A はプレイヤー B に牛 30 頭と引き換えに 10 穀物を与える、ということはおわかりでしょう。

しかし、インタラクティブで一度に多くのプレイヤーがいるので、チャットルームのような環境ですべてランダムに取引することで、そのようなことが可能かどうか疑問に思っていましたが、node.js問題がありました.

私は、DB の健全な状態を維持するためにトランザクションの処理とその性質が必要なrollbackDBのバックグラウンドを持っています。commitしかし、私たちがnode.jsプラスmongoDB(または他のノーSQL DB)について話している場合、それは確かにまったく異なる考え方ですが、頼らずに2つの当事者だけが関与する必要があるという意味で、取引をどのように処理できるかわかりません何らかの形のロックに、しかし確かにそれが目的ではありませんnode

私はまだ何も見つけていませんが、node.jsとても新しいので、それは私を驚かせません.

更新私はトランザクションのメカニズム、特に銀行スタイルのトランザクションを認識していますが、これは同じことではありません。明確にしていないかもしれませんが、問題は、プレイヤー B がバイヤーのコミュニティに何かを販売していることです。

つまり、プレーヤー A がクライアント側で購入指示を開始しても、同じ頃にプレーヤー CD または E もクリックして同じ牛を購入する可能性もあります。

通常のトランザクションでは、少なくとも最初にレコード レベルのテーブル ロックを取得した人が、他の当事者がその時点で続行するのを少なくともブロックすることが期待されます。

ただし、ノードの使用の性質、特にその速度、同時処理、およびリアルタイムの更新データベースを表示するための使用は、最も遅い人 (ミリ秒を話している) が勝つことを容易に想像できることを意味します。

たとえば、プレーヤー A はプレーヤー C と同時に購入を開始します。プレーヤー A の取引が完了し、Groats がプレーヤー B に支払われ、データベース上で牛がプレーヤー A に割り当てられます。1 ミリ秒後、Cow はプレイヤー C に割り当てられます。

それが問題をよりよく説明することを願っています。

4

3 に答える 3

4

これは Node.JS とは関係ありません。Node.JS はデータベースに接続するだけで、トランザクションはデータベース自体によって行われます (Node.JS でトランザクションを手動で実装する場合を除きますが、これは少し難しい作業になる可能性がありますが、これはどの言語で記述された Web サーバーでも同じです)。

トランザクションをサポートする Node.JS で (たとえば) MySQL を簡単に使用できます。あなたが求めている質問は、MongoDB でトランザクションを実行できますか? 答えは「いいえ」と「はい」です。

いいえ、MongoDB はそのままではトランザクションをサポートしていないためです。

はい、いくつかのトリックを使用してトランザクションをエミュレートできるためです。たとえば、この記事を参照してください。

于 2012-07-25T16:41:02.280 に答える
2

私は、ウォーターラインと呼ばれる node.js 用の oss アプリケーションレベルのトランザクション データベースに取り組んでいます。

完全な CRUD ミュートから始めましたが、すぐにそれがかなり難しいことに気付きました。それはデータベースに任せたほうがいいです。ただし、データベースを切り替えて、コードにとらわれないようにしたい場合もあります。次に、トランザクションという名前の、次の最も簡単な部分に単純化します。

そのため、ロールバックのサポートは組み込まれていません (今のところは自分で行う必要があります) が、少なくとも Waterline は同時アクセスを防ぎます。

あなたの例 (あなたが express/connect/ 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});
               });

            });
         });
      });

   });
}

それが役立つことを願っています。私はあなたのフィードバックを歓迎します (そして多分コミットしますか?)

于 2012-12-26T18:04:30.750 に答える
2

ドキュメント データベースで銀行スタイルのトランザクションを実行するには、トランザクション ログ パターンを使用するのが一般的です。このパターンでは、各トランザクションを独自のドキュメントとして記述します。各勘定残高に対応する伝票を維持していません。代わりに、クエリ時にトランザクション ドキュメントをロールアップして、現在の残高を取得します。

Couchbase map reduce に適用できる例を次に示します: http://guide.couchdb.org/draft/recipes.html

于 2012-08-07T22:31:30.687 に答える