仮予約テーブルパターン
1. 目的
- ECサイトなどで決済処理を実装する時、商品の在庫と仮押さえを実現する必要が発生する
2. 課題
3. 解決策
予約テーブルを導入
- 予約テーブルを導入し、ユーザーが選択した商品と個数を管理する
- 買い物カゴやカート機能と同義
-- インデックスやFKなどは省略
-- アイテムテーブル
CREATE TABLE items (
id BIGINT PRIMARY KEY,
total_capacity INT NOT NULL,
-- その他リソース情報
);
-- 予約テーブル
CREATE TABLE reservations (
id BIGINT PRIMARY KEY,
item_id BIGINT NOT NULL,
user_id BIGINT NOT NULL,
quantity INT NOT NULL,
status VARCHAR(20) NOT NULL, -- 'pending', 'confirmed', 'cancelled', 'expired'
reserved_at TIMESTAMP NOT NULL,
confirmed_at TIMESTAMP,
expires_at TIMESTAMP NOT NULL
);
- 在庫が存在するかは以下のようなクエリで確認できる
- 決済直前に在庫数を確認し、在庫があるようなら決済実行、在庫が無いなら決済を失敗させるというような処理を行う
SELECT
items.total_capacity - COALESCE(SUM(reservations.quantity), 0) AS available
FROM items
LEFT JOIN reservations ON items.id = reservations.item_id
AND reservations.status IN ('pending', 'confirmed')
WHERE items.id = ?
GROUP BY items.id;
予約テーブルのクリーンアップ処理も追加する
- 予約テーブルのライフサイクルはユーザーの商品選択から決済までの間のみ
- 短命のデータかつ商品選択の度にレコードが増加していく
- また、商品選択したままサイトから離脱することで在庫の抱え落ちが発生してしまう
- したがって、不要なデータのクリーンアップや在庫の復活処理が必要になる
- データのクリーンアップや在庫復活処理はバッチ処理で行うことになる
4. メリット
5. デメリット
6. 注意
参考資料