ポイント: MongoDBトランザクションは操作をグループ化することでデータの一貫性を確保し、販売のようなシナリオにおいて重要です。これらはレプリケーションとクラスタ化されたセットアップが必要ですが、パフォーマンスに影響を与える可能性があり、ドキュメントの埋め込みがより効率的な代替手段となることがあります。
- トランザクションはデータの整合性を維持するために不可欠です。
- パフォーマンス向上のためにドキュメントを埋め込むことを検討してください。
コンピュータサイエンスにはACID(原子性、一貫性、分離性、耐久性)、原子、および参照整合性という概念があります。どの用語を知っているかは、主にあなたの年齢によります。私は最後の用語を知っていますが、それは私の年齢の手がかりを与えます。
基本的に、これらすべての用語は同じことを意味します: コンピュータは論理的に不整合なトランザクションのセットをもたらすトランザクションを排除すべきです。
なぜこれが重要なのか?
販売注文と在庫管理システムがあると仮定しましょう。販売を行うと、手持ちの在庫が減少します。しかし、販売トランザクションが成功し、在庫の更新が失敗した場合、データベースはもはや一貫性がなくなります: 在庫は販売と一致しません。
それを避ける方法は、2つのトランザクションを1つの大きなトランザクションにまとめることです。Oracleデータベースプログラマーはこれをbeginとcommitステートメントとして知っています。MongoDBも同じ概念をサポートしており、以下のように説明します。
パフォーマンスの影響
MongoDBはトランザクションをサポートしていますが、パフォーマンスの問題から、ドキュメントをJSON配列として埋め込む方が良いと強調しています。言い換えれば、1つのアイテムとその関連データのすべてのデータを1つのドキュメントに入れます。
Oracleプログラマーは、これが正規化されていないデータベースをもたらすと言うでしょう。しかし、それは重要ではありません。ビッグデータデータベースはその概念を排除し、2つのレコードに同じデータを保存することは問題ないと言っています。彼らの焦点は速度にあり、何かを2回保存するために余分なディスクスペースを使用することは問題ではありません。なぜなら、ストレージはメインフレームやSolarisサーバーの日々よりも安くなったからです。
言い換えれば、ZIPコード29607とGreenville, SCを2つのレコードに持つことは問題ありません。RDBMSアプローチのように、ZIPコードテーブルを別のエンティティとして保持する必要はありません。
トランザクションの説明
これを行うには、クラスタ化されたMongoDBインストールが必要ですが、ラップトップ上にサーバーのみを持つクラスターを持っているふりをすることができます。単一のノードのみをインストールすることによって、レプリカがオフラインであるふりをします。言い換えれば、以下の手順に従ってください。ただし、/etc/mongodConfig.confのセクションを削除し、1つのサーバーのセットアップのみを行います。
sharding:
clusterRole: configsvr
トランザクションを使用するには、レプリケーションをオンにし、シャーディングをオフにする必要があります。シャーディングされたデータベースのサポートはMongoDB 4.2に付属しています。以下に、4.0.5を使用します。
データの作成
mongoシェルを開き、製品と販売コレクションを作成し、在庫に1つの製品を追加します。製品123の100アイテムを追加します。
use products
db.createCollection("products")
db.createCollection("sales")
db.products.insert({product: 123, count: 100})
次に、製品123の4アイテムを販売します。その結果、在庫には96アイテムが残ります。したがって、販売トランザクションを追加し、在庫カウントを96に更新します。以下に示します。
そのコードをMongoDBシェルに貼り付けるか、JavaScriptテキストファイルに保存し、load('<file name>')を使用して実行します。
session = db.getMongo().startSession( { readPreference: { mode: "primary" } } );
productsCollection = session.getDatabase("products").products;
salesCollection = session.getDatabase("products").sales;
session.startTransaction( { readConcern: { level: "snapshot" }, writeConcern: { w: "majority" } } );
try {
salesCollection.insertOne( {
product: 123,
count: 4
}
);
productsCollection.update(
{ product: 123 },
{ $set:
{
count: 96
}
}
);
} catch (error) {
session.abortTransaction();
throw error;
}
session.commitTransaction();
session.endSession();
コードの説明
まず、これが機能したかどうかをテストします:
db.products.findOne();
{
"_id" : ObjectId("5cb8ccb664ae78fe855e9431"),
"product" : 123,
"count" : 96
}
コードの重要な部分は:
| session.startTransaction( { readConcern: { level: "snapshot" }, writeConcern: { w: "majority" } } ); | トランザクションを開始します。 |
|
session.commitTransaction(); session.endSession(); |
トランザクションをコミットします。これは、2つのステートメント間のトランザクションがtry-catchブロックのおかげでうまくいった場合にのみここに到達します。 |
| session.abortTransaction() | どちらのトランザクションもコミットしないことを意味します。 |
| productsCollection.update( { product: 123 }, { $set: { count: 96 } } ) |
これはdb.collection.update(query to find record, what fields to update)の形式です。 製品123を更新し、カウントを96に設定します。 |
トラブルシューティング
既存のインストールでこれを行おうとしている場合、レプリケーションをオンにしなかったり、シャーディングをオフにしなかったり、コードに不合理なステートメントを含めたりすると、次のいずれかのエラーが発生します:
- トランザクション番号はレプリカセットメンバーまたはmongosでのみ許可されます。
- マルチドキュメントトランザクションは、4.2を使わない限り、シャーディングされたクラスターでは実行できません。
- トランザクションはfeatureCompatibilityVersion 4.0でのみサポートされています。詳細については、http://dochub.mongodb.org/core/4.0-feature-compatibility を参照してください。
MongoDBガイド
- MongoDB概要: MongoDBの使い始め
- UbuntuとMacにMongoDBをインストールする方法
- MongoDBでデータベースを作成する
- MongoDBシェル基本コマンド
- MongoDB Compass: Mongo GUIの使用
- MongoDBロールベースのアクセス制御(RBAC)の説明
- MongoDBプロジェクションとプロジェクションオペレーターの説明
- MongoDB集約関数の説明
- MongoDBのソート: sort()メソッドと例
- MongoDBでプッシュとプルオペレーターを使用する
- MongoDBの$unwindの使い方
- 23の一般的なMongoDBクエリオペレーターとその使い方
- MongoDBジオロケーションクエリの例
- MongoDBトランザクションの紹介
- MongoDBインデックス: トップインデックスタイプとその管理方法
- 知っておくべきMongoDBのトップコマンド
- MongoDBレプリケーション: 完全な紹介
- MongoDBクラスターのセットアップ方法
- MongoDBシャーディング: 概念、例、およびチュートリアル
- MongoDB Atlas: 管理されたMongoDBの設定および使用
- MongoDBをDockerコンテナとして実行する方法
- MongoDBのメモリ使用量、管理、および要件
- MongoDBバックアップ用のmongodumpの使い方
- MongoDBバックアップを復元するためのmongorestoreの例
- PyMongoの使い方
- MongoDBとNodeJSのためのMongooseの使い方
- MongoDBチートシート
- MongoDB対Cassandra: NoSQLデータベースの比較
- PostgreSQL対MongoDB: データベースの比較
- MySQL対MongoDB: データベースの比較
- MongoDB認証: 入門
これらの投稿は私自身のものであり、必ずしもBMCの立場、戦略、または意見を表しているわけではありません。