5

私は2つの既存のコレクション「A」と「B」を持っています。その間、B への書き込みを許可せずに、「B」の名前を「C」に変更し、「A」の名前を「B」に変更する必要があります。名前の変更自体がグローバル ロックをアクティブにしますが、名前の変更の間に書き込みが発生しないようにする必要があります。これは可能ですか?

これが私のコードです:

db.B.renameCollection('C')
                           <-- prevent writes from occurring to B in between commands
db.A.renameCollection('B')

編集: 私は mongodb バージョン 1.8.1 を使用していますが、現在、バージョンを変更することはできません。

4

5 に答える 5

4

「renameCollection」という名前の関数を作成し、それにロックをかけることができます:

db.runCommand({eval:renameCollection,args:["Collection1","Collection2"],nolock:false});

ロックにより、この種の操作を安全に実行し、リクエストを待機させることができます

于 2014-10-17T13:57:33.577 に答える
4

Mongodb 自体はこれを処理できません。これを行う唯一の方法は、カスタム コードを使用することです。

これがアプリで一度だけ発生する場合 (コレクションの名前を変更することは頻繁に行われるものではないと思います)、データベースで「コレクション db.B」を意味するフラグを検索するという、より「積極的な」アプローチを取ることができます。名前が変更されましたが、db.A はまだ'. サーバーに書き込みを送信する前にすべての書き込みでこれをチェックし、フラグが設定されている場合にのみ返す場合、db.B の名前が変更された後、アプリが db.A に書き込むことを防ぐことができます。

これは明らかにパフォーマンスに影響を与えるため、これは「アグレッシブ」なアプローチだと考えています (それでも、読み取りは非常に高速なので、おそらく感じないでしょう)。

アプリが (Web ファームではなく) 単一の Web サーバー上で実行される場合、セマフォなどのスレッド同期ツールを使用するか、フラグ I として使用されるスレッド セーフ変数を使用して、Web アプリ自体に同期メカニズムを設定できます。上で提案した。(使用しているサーバー側のテクノロジによって異なります)

于 2012-11-06T08:46:46.827 に答える
3

ご想像のとおり、これは不可能です。トランザクションのサポートはなく、アトミック操作のみです。

于 2012-11-06T05:06:40.403 に答える
1

MongoDB にはトランザクションの名前変更の意味がありません。実際、SQL がこの場合もそうするかどうかはわかりませんが、サーバー側のプログラミングとロック コレクションを少し使用すれば、これを実現できます。

サーバー側の言語から、ロックテーブルに行を書き込んでいる間にコマンドを起動できます.Bに対する各クエリはロックをチェックし、見つからない場合は書き込みます。

これは単純な方法ですが、サーバー側のコードとデータベースの間に標準化されたクエリ レイヤーが格納されていない非常にセグメント化されたコード ベースがある場合は特に、少し面倒です。

また、シャードされたコレクションでは機能しないことにも注意してくださいrenameCollection。おそらくすでにそれを知っているでしょうが、とにかくそれを言うと思いました. シャード コレクションの場合は、コピー OP を介して代わりにコレクションを「移動」することをお勧めします。

于 2012-11-06T08:27:53.997 に答える