実装

どちらにも「予約されました」 — await ひとつが分けるもの

著者: makemind · 2026年7月13日

予約の道具で最も悪い失敗は、予約が取れないことではない。

二人ともに「ご予約されました」を送ることだ。取れなければやり直せばいいが、どちらも取れたと言われれば、その次は人が電話で解決することになる。

二つの処理、同じ説明

このサンプルにはスロットを取る処理が二つある。言葉で説明すると完全に同じだ — 空いているか見て、空いていれば取る。

一方はこうだ。

// 1. Look.
final free = slot.takenBy == null;

// 2. Anything at all in here — a database round trip, a payment check, a
//    log write, a lookup of the customer's name — hands control to
//    whatever else was in flight.
await Future<void>.delayed(Duration.zero);

// 3. Write, using what was true in step 1.
if (free) { slot.takenBy = who; ... }

もう一方はこうだ。

if (slot.takenBy != null) {
  return '$at is already taken by ${slot.takenBy}';
}
slot.takenBy = who;
slot.confirmations.add(who);

await Future<void>.delayed(Duration.zero); // the slow part, after the claim

同じ await が位置だけ違う。 前者は確認と記録のにあり、後者は記録のにある。

そしてその位置が二重予約を作る。

実際に起こす

unsafe -> Suh:  "CONFIRMED 10:30 for Suh"
unsafe -> Park: "CONFIRMED 10:30 for Park"
unsafe result: 1 slot(s) confirmed to more than one person
TODAY · 1 OF 4 TAKEN — 10:30 Park, told yes: Suh, Park.「1 slot(s) confirmed to more than one person」
TODAY · 1 OF 4 TAKEN — 10:30 Park, told yes: Suh, Park.「1 slot(s) confirmed to more than one person」

画面が現実の症状を正確に見せている。 スロットの持ち主はParkひとりなのに、「予約された」と言われた人は二人だ。

これが実際の店で起きる形だ。帳簿は一人、扉の前には二人が来る。

だからサーバーは確定を送った相手を全員覚えている。

/// Everybody who has ever been told they got this slot. In a correct
/// booking system this never has more than one name in it, which is exactly
/// why it is worth keeping.
final confirmations = <String>[];

正常なら常に一人だけの一覧だ。常に一人でなければならない一覧こそ、数えてみる値打ちがある。

そして起こらないようにする

同じ二人、同じ時間、隙間だけ閉じて。

--- cleared, same two people, same slot, gap closed ---
safe -> Suh:  "CONFIRMED 10:30 for Suh"
safe -> Park: "10:30 is already taken by Suh"
safe result: nobody was told yes twice
TODAY · 1 OF 4 TAKEN — 10:30 Suh, told yes: Suh.「nobody was told yes twice」
TODAY · 1 OF 4 TAKEN — 10:30 Suh, told yes: Suh.「nobody was told yes twice」

拒否が「失敗しました」ではなく「Suhさんが取りました」だ。 二人目が知るべきなのは自分が失敗したという事実ではなく、その枠が出たという事実であり、そうしてはじめて次の時間を選べる。

このコンテンツは開発者以上が必要です

サインインしてプランをアップグレードすると続きを読めます。

プランを見る
Twitter