新規ユーザー登録の一環として。事前にコンパイルされたリスト (テーブル) からリソース (この場合は Solr コア) を割り当てます。
5 人のユーザーがサインアップする場合、5 つの異なるコアを割り当てる必要があります。ユーザーが正常に登録された場合、割り当ては最終的なものになります (以下の図を参照してください)。
しかし、実際には、新規ユーザーを同時に登録すると、異なる行を選択するのではなく、同じ行を求めて競合します。X が登録するのに 5 秒かかる場合、X の「期間」内にある Y と Z の登録は、X によって同じ行を求めて競合するため失敗します。
質問: 1 秒間に 100 件のサインアップなどの高い同時実行性がある場合でも、トランザクションを競合なしで選択するにはどうすればよいですか?
table: User
user_id name core
1 Amy h1-c1
2 Anu h1-c1
3 Raj h1-c1
4 Ron h1-c2
5 Jon h1-c2
table: FreeCoreSlots
core_id core status
1 h1-c1 used
2 h1-c1 used
3 h1-c1 used
4 h1-c2 used
5 h1-c2 used #these went to above users already
6 h1-c2 free
7 h1-c2 free
8 h1-c2 free
9 h1-c2 free
ものが分離された場合の疑似コード:
sql = SQLTransaction()
core_details = sql.get("select * from FreeCoreSlots limit 1")
sql.execute("update FreeCoreSlots set status = 'used' where id = {id}".format(
id = core_details["id"]))
sql.execute("insert into users (name,core) values ({name},{core})".format(
name = name,
id = core_details["id"]))
sql.commit()
1 秒間に 100 件のサインアップが発生すると、最初の行をめぐって競合し、重大FreeCoreSlots
な失敗を引き起こします。
解決策としてテーブル内のすべての行をロックする InnoDB SELECT ... FOR UPDATE ステートメントのように select... for update がありますが、分離を下げることを提案しているようです。この方法は正しい方法ですか?