二重リクエストを防ぐための整理
前提
MYSQL8.0
要件
並列でからリクエストをユーザ毎にリクエストを防いで、不整合をなくしたい
ただし新規作成も考慮すること
よくあるSELECT FOR UPDATEだとデータがないパターンだと、ネクストキーロックがかかってしまう。
userなど必ず存在してるデータに対して行ロックが発生する
上記は、設計上存在しない場合は利用できない。デメリットとしては、意図しない他の処理をブロックしてしまう
解決策
ロックテーブルを作る
あらかじめユーザごとに1つのレコードをインサートしておく
SELECT FOR UPDATEする
データベースのアドバイザリーロック用の関数
GET LOCK\RELEASE LOCK
セッションを変えることはできない
アプリケーション上でこねる
最初に存在チェック
なければinsert
SELECT FOR UPDATE
大事なのは二重リクエストを防ぐこと
Lockをかけずに、
Rate Limitの仕組みで実現
フロー
先にInsert する
時間を見て、n秒以内にリクエストしたカウントが2以上ならエラーで返す
懸念
二重で同じリクエストきたら、どちらもエラーになる
ユーザ目線ではエラーになった方が良い
どういうパターンだと使えるか
二重リクエストに対する許容範囲
二重リクエストは意図していないから、エラーにしても良い(必ずどちらか1つを通すもしくは、両方を通す必要がある場合は、向いていない」
タイミングによっては一つだけ通るパターンもあるが許容できるか