4

私はGunicornを使用して、NginxでFlaskアプリ(SQLAlchemyを介してDBに接続する)をホストしています。現在、Gunicornは合計5人のワーカーを使用するように構成されています。

簡単に言うと、ボタンが押されると、アプリケーションはDBをチェックして、アイテムが使用可能かどうかを確認し、使用可能かどうかをユーザーに提供します。

ただし、Gunicornで5人のワーカーを使用している場合、2人のユーザーが同時にボタンを押すと、両方にアイテムが与えられます。ワーカーを1人に減らしたところ、この問題は解決しました。この問題を解決するにはどうすればよいですか?

4

1 に答える 1

4

これは、Gunicorn の問題ではなく、標準的な同時実行制御の問題のようです。

問題はおそらく、「DB のチェック」が次のように実装されていることです。

assign_item(アイテムX、ユーザーU):

  1. アイテム X が 1 つのクエリで利用可能であることを確認する
  2. アイテム X をユーザー U に割り当て、その値を返します。

2 人のユーザー (A と B) がアイテム X を同時に要求しようとすると、assign_item(X, A) はワーカー #1 で実行され、assign_item(X, B) はワーカー #2 で実行されます。

ワーカー #1 が assign_item(X, A) の最初の行を実行し、次にワーカー #2 が assign_item(X, B) の最初の行を実行することが可能です。この時点で、両方のチェックが True を返しました。アイテムが利用可能です。したがって、両方のワーカーがそれぞれの次の操作を実行し、同じアイテムをユーザーに返します。

データベースを使用してこれを解決する方法は、assign_item で BEGIN TRANSACTION と END TRANSACTION を使用して、2 つの操作がアトミックに行われるようにすることです。

これはよく知られた問題です。詳細については、http://en.wikipedia.org/wiki/Concurrency_controlを参照してください。

于 2013-03-01T23:05:17.260 に答える