背景
クライアントは、1 日の予算を設定したサービスを使用しています。これは前払いサービスで、ユーザーの予算から毎日特定の金額を割り当てます。
テーブル:
- 予算- 1 日に使用できる金額
- お金- クライアントの実質残高
- money_allocated -今日使用できる金額から差し引かれた金額 (予算に基づく)
数分ごとに実行され、以下をチェックする cron ジョブがあります。
- ユーザーが特定の日にmoney_allocatedを持っている場合
- money_allocated >=予算の場合(ユーザーは日中に予算を増やすことができます)
最初のケースでは、1 日の予算の全額を割り当てます。後者では、その日の予算と既に割り当てられている金額との差額を割り当てます (この場合、同じ日にmoney_allocatedに追加のレコードを作成します)。
割り当てには 2 つの段階があります。最初のラウンドでは、ステータスが「保留中」(割り当てが要求されている) の行を追加し、別の cron がすべての「保留中」の割り当てをチェックし、ユーザーに十分なお金がある場合はお金をmoneyからmoney_allocatedに移動します。これにより、ステータスが「完了」に変わります。
問題
アプリケーション サーバーのクラスター (NLB の下) があり、上記の cron ジョブはそれらのそれぞれで実行されます。つまり、お金が誤って複数回割り当てられる可能性があります (または、間違った "既に割り当てられた" トリガーを実装すると、まったく割り当てられない)。
私たちのオプションは次のとおりです。
- 1 台のサーバーでのみ cron ジョブを実行します。
- (client_id, date, amount) のようにmoney_allocatedに一意のインデックスを追加します。クライアントが予算を 2 倍にしたり、1 日に同じ金額を複数回増やしたりしても、特定の日に追加のお金を割り当てることはありません。
予算の各動きを記録し、すべての割り当てを「その日の最初の割り当て」または「予算の変更 (id xxx)」にリンクするオプションがあります(これも一意のインデックスに追加します)。ただし、これは十分にセクシーに見えません。
他のオプションはありますか?どんなアドバイスでも大歓迎です!