web-dev-qa-db-ja.com

MongoDBでのトランザクションサポート

私はMongoDBを初めて使用します。私はそれを読んだMongoDB does not support multi-document transactionshere http://docs.mongodb.org/manual/faq/fundamentals/

2つのコレクション(AとB)にアトミックにデータを保存したい場合、MongoDBを使用してそれを行うことはできません。つまり、Bの場合に保存が失敗した場合でも、Aはデータを保持します。大きなデメリットではないですか?

それでも、人々はRDBMSではなくMongoDBを使用しています。どうして?

14
Anand

MongoDBはmulti-documentトランザクションをサポートしていません。

ただし、MongoDBは単一のドキュメントに対してアトミック操作を提供します。多くの場合、これらのドキュメントレベルのアトミック操作は、リレーショナルデータベースでACIDトランザクションを必要とする問題を解決するのに十分です。

たとえば、MongoDBでは、関連データをネストされた配列またはネストされたドキュメントに1つのドキュメント内に埋め込み、ドキュメント全体を1回のアトミック操作で更新できます。リレーショナルデータベースは、複数のテーブルと行を持つ同じ種類のデータを表す場合があり、データをアトミックに更新するにはトランザクションサポートが必要になります。

9
Tony

MongoDBはトランザクションをサポートしていませんが、1つのドキュメントの保存はアトミックです。

したがって、アトミックに保存する必要のあるすべてのデータが1つのドキュメントに配置されるように、データベーススキーマを設計することをお勧めします。

4
stalk

MongoDBはリレーショナルDBのようにトランザクションをサポートしていません。トランザクションでのACIDの仮定は、MySQLのストレージエンジンによって提供される完全に異なる機能です

MySQLのInnoDBエンジンの機能のいくつか:

  • クラッシュリカバリ
  • ダブル書き込みバッファ
  • 自動コミット設定
  • 分離レベル

これはMongoDBコミュニティが言わなければならないことです:

MongoDBは、従来のロックまたはロールバックを伴う複雑なトランザクションをサポートしていません。

MongoDBは、軽量、高速、パフォーマンスの予測可能性を目指しています。トランザクションサポートを非常にシンプルに保つことで、MongoDBは、特に多数のデータベースサーバープロセスを備えたパーティション化またはレプリケートされたシステムに対して、より優れたパフォーマンスを提供できます。

トランザクションの目的は、複数の操作が行われている間、データベース全体の一貫性を維持することです。

ただし、ほとんどのリレーショナルデータベースとは異なり、MongoDBは単一のホストで実行するようには設計されていません。これは、複数のシャードのクラスターとしてセットアップするように設計されており、各シャードは複数のサーバーのレプリカセットです(オプションで地理的に異なる場所にあります)。

ただし、トランザクションを可能にする方法をまだ探している場合:

  • Mongoが提供するドキュメントレベルのアトミック性を使用してみてください
  • 2フェーズコミット in Mongoは、基本的な操作のための単純なトランザクションメカニズムを提供します
  • mongomvccはmongoの上に構築されており、彼らが言うようにトランザクションもサポートしています
  • MySQLとMongoのハイブリッド
3
keshav

MongoDB 4.0では、マルチドキュメントACIDトランザクションのサポートが追加されました。参考のために 参考文献を参照

2
Mithilesh Jha

この質問はかなり古いものですが、このページに出くわした人は、 fawn を使用できます。これは、この正確な問題を解決するnpmパッケージです。開示:私はそれを書いた

2つの銀行口座があり、1つはJohn Smithに属し、もう1つはBrokeIndividualに属しているとします。 JohnSmithからBrokeIndividualに$ 20を送金したいとします。すべての姓と名のペアが一意であるとすると、次のようになります。

var Fawn = require("fawn");
var task = Fawn.Task()

//assuming "Accounts" is the Accounts collection 
task.update("Accounts", {firstName: "John", lastName: "Smith"}, {$inc: {balance: -20}})
  .update("Accounts", {firstName: "Broke", lastName: "Individual"}, {$inc: {balance: 20}})
  .run()
  .then(function(){
    //update is complete 
  })
  .catch(function(err){
    // Everything has been rolled back. 

    //log the error which caused the failure 
    console.log(err);
  });

警告:タスクは現在分離されていません(それに取り組んでいます)。したがって、技術的には、MongoDBが機能するという理由だけで、2つのタスクが同じドキュメントを取得して編集する可能性があります。

これは実際には、チュートリアルサイトの2フェーズコミットの例の一般的な実装にすぎません。 https://docs.mongodb.com/manual/tutorial/perform-two-phase-commits/

1
oj_1boss

ここで説明する2フェーズコミットアプローチを使用したマルチドキュメントの更新または「マルチドキュメントトランザクション」: http://docs.mongodb.org/manual/tutorial/perform-two-phase-commits/

1
Rahatur

バージョン4.0以降、MongoDBはマルチドキュメントトランザクションのサポートを追加します。したがって、MongoDBでACIDが保証されたドキュメントモデルのパワーを利用できます。 MongoDBのトランザクションは、リレーショナルデータベースのトランザクションのようになります。

詳細については、次のリンクにアクセスしてください: https://www.mongodb.com/blog/post/multi-document-transactions-in-mongodb?jmp=community

0
Pranab Sharma