0

アプリケーション ロジック (特に OAuth アクセス トークンの更新時) で競合状態を防ぐための解決策を見つけようとしていますが、バックエンド データベースがたまたま mongodb になっています。

MySQL のバックグラウンドから来て、私は使用に慣れてGET_LOCKおり、PHP でブロッキングを処理するための関連関数です。Mongo には MySQL のGET_LOCK機能に類似した機能がありますか、それとも PHP のファイル ロックなどを使用する必要がありますか?

flock()この状況に適した(または適切な)代替手段はありますか、それともファイルの読み取りおよび書き込み時にのみ使用することを意図していますか?

編集:

私が防止しようとしている競合状態は次のとおりです。

  1. インスタンス A は、OAuth アクセス トークンの有効期限が近づいていることを通知します

  2. インスタンス B は、OAuth アクセス トークンの有効期限が近づいていることを通知します

  3. インスタンス A は、リモート サーバーから更新された OAuth アクセス トークンを要求し、それを取得します。

  4. インスタンス B は、同じサーバーから更新された OAuth アクセス トークンを要求し、拒否されます (サーバーは、セキュリティ上の予防措置として、ステップ 3 のアクセス トークンを無効にする可能性があります)。

  5. インスタンス A は結果をデータベースに保存します

  6. インスタンス B は結果をデータベースに保存します

4

1 に答える 1

3

MongoDB を使用して名前付きミューテックスまたはロックをシミュレートする場合は、findAndModifyを使用して特別なコレクションを作成し、ドキュメントを作成することをお勧めします。db.my_lock と呼ぶこともできます。

db.my_lock.save({"IMREFRESHINGAUTHTOKEN":false});

ここで、ステップ 2 と 3 の間に findAndModify を追加して「ロック」を取得します。

db.my_lock.findAndModify(
        query: {"IMREFRESHINGAUTHTOKEN":false},
        update: {$set: {"IMREFRESHINGAUTHTOKEN": true}, ...}
);

最初に「ロック」に到達すると、このオブジェクトが返されます (そして、最初のフィールドを true に設定する必要があります。タイムスタンプ、接続番号、プロセス ID、またはその他の識別子を使用して 2 番目のフィールドを設定することをお勧めします)。ロックを永久に保持しないように、クラッシュしたプロセスの後にクリーンアップします)。

レースに「負けた」場合、「IMREFRESHINGAUTHTOKEN」に一致するものは何も返されず、レースに負けてあきらめたことがわかります(または、ロックのタイムスタンプを確認して、古くて古いかどうかを確認してください) .

これは、「コレクション」全体に対するスタンドアロンの単一ロックを表します。もちろん、これを格納された OAuth トークンの追加フィールドとして実装し、期限切れに気付いたスレッドと同じ数のトークンを一度に更新することができます。

お役に立てれば。

于 2012-06-17T07:18:44.230 に答える