跳至正文
Lynn LeeMYSQL / LEARNING LAB

EXPERIMENT 04 / BUSINESS INVARIANT

两边都提交了,却无人值班。

两名医生各自在“还有别人值班”时才撤岗。事务成功提交,仍可能共同破坏业务规则。

这里展示真实 MySQL 8.4 运行记录;浏览器不执行 SQL。实验限于固定成员,不对范围插入、任意已有快照或性能作出保证。

不变量:SUM(on_call) ≥ 1。初始状态 (1,1),各有一次撤岗请求。独立 Python 模型枚举两种串行请求顺序,只允许 (0,1) 或 (1,0)。两方提交后,另一个自动提交观察者独立读取 MySQL 终值。

实测首跑 JSON · 停止重启后复跑 JSON · 生命周期与反例验收 · 可修改 SQL

先预测,再阅读结果

  1. 双方先完成计数,再开始写入。单行 AND on_call=1 能否保护跨行规则?
  2. 双方先建立 RR 快照,再竞争独占守卫锁。之后的普通计数会更新吗?
  3. 在首次一致性读之前获取守卫锁,或直接 FOR UPDATE 读取名单。什么证据能证明 B 真正等待?

首轮实测结果

隔离级别strategyA 计数B 计数剩余值班串行可达
READ COMMITTEDunguarded220否
READ COMMITTEDlate_guard211是
READ COMMITTEDguard_first211是
READ COMMITTEDlocking_roster211是
REPEATABLE READunguarded220否
REPEATABLE READlate_guard220否
REPEATABLE READguard_first211是
REPEATABLE READlocking_roster211是

上表每行都有两次成功提交;是否批准撤岗是另一个决策。每份记录重复三轮,第二轮交换医生 ID;第二份记录来自停止、重启后的复跑。时间只用于检查执行顺序,不作性能基准。

差异来自哪里

运行、修改 SQL、复跑

python lab.py doctor
python lab.py start
python lab.py oncall --output .local/oncall-first.json
python lab.py stop
python lab.py start
python lab.py oncall --output .local/oncall-repeat.json
python scripts/validate_oncall.py .local/oncall-first.json .local/oncall-repeat.json
cp sql/oncall.json .local/oncall-sql.json
# Edit .local/oncall-sql.json, preserve the baseline
python lab.py oncall --sql-file .local/oncall-sql.json --output .local/oncall-edited.json
python lab.py stop
  1. 基线:修改前解释失败场景为何不在模型允许的串行终值内。检查参数绑定,确认每个会话实际修改了哪名医生。
  2. 等价改写:将 count 改为 SELECT COALESCE(SUM(on_call),0) AS n FROM oncall_roster WHERE shift_id=1。复跑完整矩阵,固定名单下应保留相同语义。
  3. 负对照:从 guard 查询中删除 FOR UPDATE。所需 B→A 等待边消失,运行器必须在期限内失败,且不能产生成功 JSON。这是在拒绝失效的调度前提,并非新的终值证明。
  4. 解释把普通读取提前到 guard_first 之前,为何就变成 late_guard。用已有 late_guard RR 记录作为反例,再对比 RC。

检查实际证据

READ COMMITTED / unguarded / 剩余 0

独立终值与模型判断

{
  "final_rows": [
    {
      "doctor_id": 1,
      "on_call": 0
    },
    {
      "doctor_id": 2,
      "on_call": 0
    }
  ],
  "oracle": {
    "on_call_count": 0,
    "invariant_holds": false,
    "serially_reachable": false,
    "allowed_serial_states": [
      [
        0,
        1
      ],
      [
        1,
        0
      ]
    ]
  },
  "decisions": {
    "B": {
      "doctor_id": 2,
      "observed_count": 2,
      "approved": true,
      "outcome": "committed"
    },
    "A": {
      "doctor_id": 1,
      "observed_count": 2,
      "approved": true,
      "outcome": "committed"
    }
  }
}

这里不声称观测到锁等待,屏障依据是双方已完成的读取。

实际执行时间线,含 SQL 参数

[
  {
    "step": 1,
    "elapsed_ms": 18.576,
    "actor": "A",
    "action": "submit",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED"
  },
  {
    "step": 2,
    "elapsed_ms": 19.559,
    "actor": "A",
    "action": "returned",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED",
    "rows": []
  },
  {
    "step": 3,
    "elapsed_ms": 19.568,
    "actor": "A",
    "action": "submit",
    "sql": "START TRANSACTION"
  },
  {
    "step": 4,
    "elapsed_ms": 20.126,
    "actor": "A",
    "action": "returned",
    "sql": "START TRANSACTION",
    "rows": []
  },
  {
    "step": 5,
    "elapsed_ms": 20.131,
    "actor": "B",
    "action": "submit",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED"
  },
  {
    "step": 6,
    "elapsed_ms": 21.032,
    "actor": "B",
    "action": "returned",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED",
    "rows": []
  },
  {
    "step": 7,
    "elapsed_ms": 21.035,
    "actor": "B",
    "action": "submit",
    "sql": "START TRANSACTION"
  },
  {
    "step": 8,
    "elapsed_ms": 21.464,
    "actor": "B",
    "action": "returned",
    "sql": "START TRANSACTION",
    "rows": []
  },
  {
    "step": 9,
    "elapsed_ms": 21.471,
    "actor": "A",
    "action": "submit",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1"
  },
  {
    "step": 10,
    "elapsed_ms": 22.647,
    "actor": "A",
    "action": "returned",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1",
    "rows": [
      {
        "n": 2
      }
    ]
  },
  {
    "step": 11,
    "elapsed_ms": 22.651,
    "actor": "B",
    "action": "submit",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1"
  },
  {
    "step": 12,
    "elapsed_ms": 23.208,
    "actor": "B",
    "action": "returned",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1",
    "rows": [
      {
        "n": 2
      }
    ]
  },
  {
    "step": 13,
    "elapsed_ms": 23.211,
    "actor": "coordinator",
    "action": "barrier: both initial counts completed before writes"
  },
  {
    "step": 14,
    "elapsed_ms": 23.303,
    "actor": "B",
    "action": "submit",
    "sql": "UPDATE oncall_roster SET on_call=0 WHERE shift_id=1 AND doctor_id=%s AND on_call=1",
    "parameters": [
      2
    ]
  },
  {
    "step": 15,
    "elapsed_ms": 23.328,
    "actor": "A",
    "action": "submit",
    "sql": "UPDATE oncall_roster SET on_call=0 WHERE shift_id=1 AND doctor_id=%s AND on_call=1",
    "parameters": [
      1
    ]
  },
  {
    "step": 16,
    "elapsed_ms": 24.057,
    "actor": "A",
    "action": "returned",
    "sql": "UPDATE oncall_roster SET on_call=0 WHERE shift_id=1 AND doctor_id=%s AND on_call=1",
    "rows": [],
    "parameters": [
      1
    ]
  },
  {
    "step": 17,
    "elapsed_ms": 24.06,
    "actor": "A",
    "action": "submit",
    "sql": "COMMIT"
  },
  {
    "step": 18,
    "elapsed_ms": 24.084,
    "actor": "B",
    "action": "returned",
    "sql": "UPDATE oncall_roster SET on_call=0 WHERE shift_id=1 AND doctor_id=%s AND on_call=1",
    "rows": [],
    "parameters": [
      2
    ]
  },
  {
    "step": 19,
    "elapsed_ms": 24.087,
    "actor": "B",
    "action": "submit",
    "sql": "COMMIT"
  },
  {
    "step": 20,
    "elapsed_ms": 25.498,
    "actor": "B",
    "action": "returned",
    "sql": "COMMIT",
    "rows": []
  },
  {
    "step": 21,
    "elapsed_ms": 25.822,
    "actor": "A",
    "action": "returned",
    "sql": "COMMIT",
    "rows": []
  }
]
READ COMMITTED / late_guard / 剩余 1

独立终值与模型判断

{
  "final_rows": [
    {
      "doctor_id": 1,
      "on_call": 0
    },
    {
      "doctor_id": 2,
      "on_call": 1
    }
  ],
  "oracle": {
    "on_call_count": 1,
    "invariant_holds": true,
    "serially_reachable": true,
    "allowed_serial_states": [
      [
        0,
        1
      ],
      [
        1,
        0
      ]
    ]
  },
  "decisions": {
    "A": {
      "doctor_id": 1,
      "observed_count": 2,
      "approved": true,
      "outcome": "committed"
    },
    "B": {
      "doctor_id": 2,
      "observed_count": 1,
      "approved": false,
      "outcome": "committed"
    }
  }
}
actortableindexmodestatus
Aoncall_guardPRIMARYX,REC_NOT_GAPGRANTED
Aoncall_guardNoneIXGRANTED
Boncall_guardPRIMARYX,REC_NOT_GAPWAITING
Boncall_guardNoneIXGRANTED

实际执行时间线,含 SQL 参数

[
  {
    "step": 1,
    "elapsed_ms": 7.396,
    "actor": "A",
    "action": "submit",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED"
  },
  {
    "step": 2,
    "elapsed_ms": 8.127,
    "actor": "A",
    "action": "returned",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED",
    "rows": []
  },
  {
    "step": 3,
    "elapsed_ms": 8.132,
    "actor": "A",
    "action": "submit",
    "sql": "START TRANSACTION"
  },
  {
    "step": 4,
    "elapsed_ms": 8.746,
    "actor": "A",
    "action": "returned",
    "sql": "START TRANSACTION",
    "rows": []
  },
  {
    "step": 5,
    "elapsed_ms": 8.748,
    "actor": "B",
    "action": "submit",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED"
  },
  {
    "step": 6,
    "elapsed_ms": 9.344,
    "actor": "B",
    "action": "returned",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED",
    "rows": []
  },
  {
    "step": 7,
    "elapsed_ms": 9.346,
    "actor": "B",
    "action": "submit",
    "sql": "START TRANSACTION"
  },
  {
    "step": 8,
    "elapsed_ms": 9.865,
    "actor": "B",
    "action": "returned",
    "sql": "START TRANSACTION",
    "rows": []
  },
  {
    "step": 9,
    "elapsed_ms": 9.872,
    "actor": "A",
    "action": "submit",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1"
  },
  {
    "step": 10,
    "elapsed_ms": 10.602,
    "actor": "A",
    "action": "returned",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1",
    "rows": [
      {
        "n": 2
      }
    ]
  },
  {
    "step": 11,
    "elapsed_ms": 10.606,
    "actor": "B",
    "action": "submit",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1"
  },
  {
    "step": 12,
    "elapsed_ms": 11.234,
    "actor": "B",
    "action": "returned",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1",
    "rows": [
      {
        "n": 2
      }
    ]
  },
  {
    "step": 13,
    "elapsed_ms": 11.237,
    "actor": "coordinator",
    "action": "barrier: both initial counts completed before writes"
  },
  {
    "step": 14,
    "elapsed_ms": 11.238,
    "actor": "A",
    "action": "submit",
    "sql": "SELECT shift_id FROM oncall_guard WHERE shift_id=1 FOR UPDATE"
  },
  {
    "step": 15,
    "elapsed_ms": 11.903,
    "actor": "A",
    "action": "returned",
    "sql": "SELECT shift_id FROM oncall_guard WHERE shift_id=1 FOR UPDATE",
    "rows": [
      {
        "shift_id": 1
      }
    ]
  },
  {
    "step": 16,
    "elapsed_ms": 11.996,
    "actor": "B",
    "action": "submit",
    "sql": "SELECT shift_id FROM oncall_guard WHERE shift_id=1 FOR UPDATE"
  },
  {
    "step": 17,
    "elapsed_ms": 25.861,
    "actor": "observer",
    "action": "barrier: observed lock wait",
    "waiting": "B",
    "blocking": "A"
  },
  {
    "step": 18,
    "elapsed_ms": 25.872,
    "actor": "coordinator",
    "action": "barrier: release A only after observed B→A wait"
  },
  {
    "step": 19,
    "elapsed_ms": 25.876,
    "actor": "A",
    "action": "submit",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1"
  },
  {
    "step": 20,
    "elapsed_ms": 26.724,
    "actor": "A",
    "action": "returned",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1",
    "rows": [
      {
        "n": 2
      }
    ]
  },
  {
    "step": 21,
    "elapsed_ms": 26.729,
    "actor": "A",
    "action": "submit",
    "sql": "UPDATE oncall_roster SET on_call=0 WHERE shift_id=1 AND doctor_id=%s AND on_call=1",
    "parameters": [
      1
    ]
  },
  {
    "step": 22,
    "elapsed_ms": 27.703,
    "actor": "A",
    "action": "returned",
    "sql": "UPDATE oncall_roster SET on_call=0 WHERE shift_id=1 AND doctor_id=%s AND on_call=1",
    "rows": [],
    "parameters": [
      1
    ]
  },
  {
    "step": 23,
    "elapsed_ms": 27.706,
    "actor": "A",
    "action": "submit",
    "sql": "COMMIT"
  },
  {
    "step": 24,
    "elapsed_ms": 29.426,
    "actor": "A",
    "action": "returned",
    "sql": "COMMIT",
    "rows": []
  },
  {
    "step": 25,
    "elapsed_ms": 29.495,
    "actor": "B",
    "action": "returned",
    "sql": "SELECT shift_id FROM oncall_guard WHERE shift_id=1 FOR UPDATE",
    "rows": [
      {
        "shift_id": 1
      }
    ]
  },
  {
    "step": 26,
    "elapsed_ms": 29.501,
    "actor": "B",
    "action": "submit",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1"
  },
  {
    "step": 27,
    "elapsed_ms": 30.322,
    "actor": "B",
    "action": "returned",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1",
    "rows": [
      {
        "n": 1
      }
    ]
  },
  {
    "step": 28,
    "elapsed_ms": 30.325,
    "actor": "B",
    "action": "submit",
    "sql": "COMMIT"
  },
  {
    "step": 29,
    "elapsed_ms": 31.188,
    "actor": "B",
    "action": "returned",
    "sql": "COMMIT",
    "rows": []
  }
]
READ COMMITTED / guard_first / 剩余 1

独立终值与模型判断

{
  "final_rows": [
    {
      "doctor_id": 1,
      "on_call": 0
    },
    {
      "doctor_id": 2,
      "on_call": 1
    }
  ],
  "oracle": {
    "on_call_count": 1,
    "invariant_holds": true,
    "serially_reachable": true,
    "allowed_serial_states": [
      [
        0,
        1
      ],
      [
        1,
        0
      ]
    ]
  },
  "decisions": {
    "A": {
      "doctor_id": 1,
      "observed_count": 2,
      "approved": true,
      "outcome": "committed"
    },
    "B": {
      "doctor_id": 2,
      "observed_count": 1,
      "approved": false,
      "outcome": "committed"
    }
  }
}
actortableindexmodestatus
Aoncall_guardPRIMARYX,REC_NOT_GAPGRANTED
Aoncall_guardNoneIXGRANTED
Boncall_guardPRIMARYX,REC_NOT_GAPWAITING
Boncall_guardNoneIXGRANTED

实际执行时间线,含 SQL 参数

[
  {
    "step": 1,
    "elapsed_ms": 9.927,
    "actor": "A",
    "action": "submit",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED"
  },
  {
    "step": 2,
    "elapsed_ms": 11.009,
    "actor": "A",
    "action": "returned",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED",
    "rows": []
  },
  {
    "step": 3,
    "elapsed_ms": 11.013,
    "actor": "A",
    "action": "submit",
    "sql": "START TRANSACTION"
  },
  {
    "step": 4,
    "elapsed_ms": 11.621,
    "actor": "A",
    "action": "returned",
    "sql": "START TRANSACTION",
    "rows": []
  },
  {
    "step": 5,
    "elapsed_ms": 11.63,
    "actor": "B",
    "action": "submit",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED"
  },
  {
    "step": 6,
    "elapsed_ms": 12.229,
    "actor": "B",
    "action": "returned",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED",
    "rows": []
  },
  {
    "step": 7,
    "elapsed_ms": 12.232,
    "actor": "B",
    "action": "submit",
    "sql": "START TRANSACTION"
  },
  {
    "step": 8,
    "elapsed_ms": 12.835,
    "actor": "B",
    "action": "returned",
    "sql": "START TRANSACTION",
    "rows": []
  },
  {
    "step": 9,
    "elapsed_ms": 12.84,
    "actor": "A",
    "action": "submit",
    "sql": "SELECT shift_id FROM oncall_guard WHERE shift_id=1 FOR UPDATE"
  },
  {
    "step": 10,
    "elapsed_ms": 13.554,
    "actor": "A",
    "action": "returned",
    "sql": "SELECT shift_id FROM oncall_guard WHERE shift_id=1 FOR UPDATE",
    "rows": [
      {
        "shift_id": 1
      }
    ]
  },
  {
    "step": 11,
    "elapsed_ms": 13.663,
    "actor": "B",
    "action": "submit",
    "sql": "SELECT shift_id FROM oncall_guard WHERE shift_id=1 FOR UPDATE"
  },
  {
    "step": 12,
    "elapsed_ms": 15.733,
    "actor": "observer",
    "action": "barrier: observed lock wait",
    "waiting": "B",
    "blocking": "A"
  },
  {
    "step": 13,
    "elapsed_ms": 15.737,
    "actor": "coordinator",
    "action": "barrier: release A only after observed B→A wait"
  },
  {
    "step": 14,
    "elapsed_ms": 15.74,
    "actor": "A",
    "action": "submit",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1"
  },
  {
    "step": 15,
    "elapsed_ms": 16.691,
    "actor": "A",
    "action": "returned",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1",
    "rows": [
      {
        "n": 2
      }
    ]
  },
  {
    "step": 16,
    "elapsed_ms": 16.696,
    "actor": "A",
    "action": "submit",
    "sql": "UPDATE oncall_roster SET on_call=0 WHERE shift_id=1 AND doctor_id=%s AND on_call=1",
    "parameters": [
      1
    ]
  },
  {
    "step": 17,
    "elapsed_ms": 17.423,
    "actor": "A",
    "action": "returned",
    "sql": "UPDATE oncall_roster SET on_call=0 WHERE shift_id=1 AND doctor_id=%s AND on_call=1",
    "rows": [],
    "parameters": [
      1
    ]
  },
  {
    "step": 18,
    "elapsed_ms": 17.428,
    "actor": "A",
    "action": "submit",
    "sql": "COMMIT"
  },
  {
    "step": 19,
    "elapsed_ms": 18.986,
    "actor": "A",
    "action": "returned",
    "sql": "COMMIT",
    "rows": []
  },
  {
    "step": 20,
    "elapsed_ms": 19.068,
    "actor": "B",
    "action": "returned",
    "sql": "SELECT shift_id FROM oncall_guard WHERE shift_id=1 FOR UPDATE",
    "rows": [
      {
        "shift_id": 1
      }
    ]
  },
  {
    "step": 21,
    "elapsed_ms": 19.091,
    "actor": "B",
    "action": "submit",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1"
  },
  {
    "step": 22,
    "elapsed_ms": 19.963,
    "actor": "B",
    "action": "returned",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1",
    "rows": [
      {
        "n": 1
      }
    ]
  },
  {
    "step": 23,
    "elapsed_ms": 19.967,
    "actor": "B",
    "action": "submit",
    "sql": "COMMIT"
  },
  {
    "step": 24,
    "elapsed_ms": 20.487,
    "actor": "B",
    "action": "returned",
    "sql": "COMMIT",
    "rows": []
  }
]
READ COMMITTED / locking_roster / 剩余 1

独立终值与模型判断

{
  "final_rows": [
    {
      "doctor_id": 1,
      "on_call": 0
    },
    {
      "doctor_id": 2,
      "on_call": 1
    }
  ],
  "oracle": {
    "on_call_count": 1,
    "invariant_holds": true,
    "serially_reachable": true,
    "allowed_serial_states": [
      [
        0,
        1
      ],
      [
        1,
        0
      ]
    ]
  },
  "decisions": {
    "A": {
      "doctor_id": 1,
      "observed_count": 2,
      "approved": true,
      "outcome": "committed"
    },
    "B": {
      "doctor_id": 2,
      "observed_count": 1,
      "approved": false,
      "outcome": "committed"
    }
  }
}
actortableindexmodestatus
Aoncall_rosterPRIMARYX,REC_NOT_GAPGRANTED
Aoncall_rosterPRIMARYX,REC_NOT_GAPGRANTED
Aoncall_rosterNoneIXGRANTED
Boncall_rosterPRIMARYX,REC_NOT_GAPWAITING
Boncall_rosterNoneIXGRANTED

实际执行时间线,含 SQL 参数

[
  {
    "step": 1,
    "elapsed_ms": 10.083,
    "actor": "A",
    "action": "submit",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED"
  },
  {
    "step": 2,
    "elapsed_ms": 10.702,
    "actor": "A",
    "action": "returned",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED",
    "rows": []
  },
  {
    "step": 3,
    "elapsed_ms": 10.71,
    "actor": "A",
    "action": "submit",
    "sql": "START TRANSACTION"
  },
  {
    "step": 4,
    "elapsed_ms": 11.24,
    "actor": "A",
    "action": "returned",
    "sql": "START TRANSACTION",
    "rows": []
  },
  {
    "step": 5,
    "elapsed_ms": 11.244,
    "actor": "B",
    "action": "submit",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED"
  },
  {
    "step": 6,
    "elapsed_ms": 11.721,
    "actor": "B",
    "action": "returned",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED",
    "rows": []
  },
  {
    "step": 7,
    "elapsed_ms": 11.725,
    "actor": "B",
    "action": "submit",
    "sql": "START TRANSACTION"
  },
  {
    "step": 8,
    "elapsed_ms": 12.125,
    "actor": "B",
    "action": "returned",
    "sql": "START TRANSACTION",
    "rows": []
  },
  {
    "step": 9,
    "elapsed_ms": 12.129,
    "actor": "A",
    "action": "submit",
    "sql": "SELECT doctor_id FROM oncall_roster WHERE shift_id=1 AND on_call=1 ORDER BY doctor_id FOR UPDATE"
  },
  {
    "step": 10,
    "elapsed_ms": 12.897,
    "actor": "A",
    "action": "returned",
    "sql": "SELECT doctor_id FROM oncall_roster WHERE shift_id=1 AND on_call=1 ORDER BY doctor_id FOR UPDATE",
    "rows": [
      {
        "doctor_id": 1
      },
      {
        "doctor_id": 2
      }
    ]
  },
  {
    "step": 11,
    "elapsed_ms": 12.996,
    "actor": "B",
    "action": "submit",
    "sql": "SELECT doctor_id FROM oncall_roster WHERE shift_id=1 AND on_call=1 ORDER BY doctor_id FOR UPDATE"
  },
  {
    "step": 12,
    "elapsed_ms": 15.375,
    "actor": "observer",
    "action": "barrier: observed lock wait",
    "waiting": "B",
    "blocking": "A"
  },
  {
    "step": 13,
    "elapsed_ms": 15.381,
    "actor": "coordinator",
    "action": "barrier: release A only after observed B→A wait"
  },
  {
    "step": 14,
    "elapsed_ms": 15.386,
    "actor": "A",
    "action": "submit",
    "sql": "UPDATE oncall_roster SET on_call=0 WHERE shift_id=1 AND doctor_id=%s AND on_call=1",
    "parameters": [
      1
    ]
  },
  {
    "step": 15,
    "elapsed_ms": 15.947,
    "actor": "A",
    "action": "returned",
    "sql": "UPDATE oncall_roster SET on_call=0 WHERE shift_id=1 AND doctor_id=%s AND on_call=1",
    "rows": [],
    "parameters": [
      1
    ]
  },
  {
    "step": 16,
    "elapsed_ms": 15.95,
    "actor": "A",
    "action": "submit",
    "sql": "COMMIT"
  },
  {
    "step": 17,
    "elapsed_ms": 17.832,
    "actor": "A",
    "action": "returned",
    "sql": "COMMIT",
    "rows": []
  },
  {
    "step": 18,
    "elapsed_ms": 17.877,
    "actor": "B",
    "action": "returned",
    "sql": "SELECT doctor_id FROM oncall_roster WHERE shift_id=1 AND on_call=1 ORDER BY doctor_id FOR UPDATE",
    "rows": [
      {
        "doctor_id": 2
      }
    ]
  },
  {
    "step": 19,
    "elapsed_ms": 17.88,
    "actor": "B",
    "action": "submit",
    "sql": "COMMIT"
  },
  {
    "step": 20,
    "elapsed_ms": 18.419,
    "actor": "B",
    "action": "returned",
    "sql": "COMMIT",
    "rows": []
  }
]
REPEATABLE READ / unguarded / 剩余 0

独立终值与模型判断

{
  "final_rows": [
    {
      "doctor_id": 1,
      "on_call": 0
    },
    {
      "doctor_id": 2,
      "on_call": 0
    }
  ],
  "oracle": {
    "on_call_count": 0,
    "invariant_holds": false,
    "serially_reachable": false,
    "allowed_serial_states": [
      [
        0,
        1
      ],
      [
        1,
        0
      ]
    ]
  },
  "decisions": {
    "A": {
      "doctor_id": 1,
      "observed_count": 2,
      "approved": true,
      "outcome": "committed"
    },
    "B": {
      "doctor_id": 2,
      "observed_count": 2,
      "approved": true,
      "outcome": "committed"
    }
  }
}

这里不声称观测到锁等待,屏障依据是双方已完成的读取。

实际执行时间线,含 SQL 参数

[
  {
    "step": 1,
    "elapsed_ms": 10.685,
    "actor": "A",
    "action": "submit",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ"
  },
  {
    "step": 2,
    "elapsed_ms": 11.194,
    "actor": "A",
    "action": "returned",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ",
    "rows": []
  },
  {
    "step": 3,
    "elapsed_ms": 11.198,
    "actor": "A",
    "action": "submit",
    "sql": "START TRANSACTION"
  },
  {
    "step": 4,
    "elapsed_ms": 11.938,
    "actor": "A",
    "action": "returned",
    "sql": "START TRANSACTION",
    "rows": []
  },
  {
    "step": 5,
    "elapsed_ms": 11.94,
    "actor": "B",
    "action": "submit",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ"
  },
  {
    "step": 6,
    "elapsed_ms": 12.602,
    "actor": "B",
    "action": "returned",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ",
    "rows": []
  },
  {
    "step": 7,
    "elapsed_ms": 12.605,
    "actor": "B",
    "action": "submit",
    "sql": "START TRANSACTION"
  },
  {
    "step": 8,
    "elapsed_ms": 13.091,
    "actor": "B",
    "action": "returned",
    "sql": "START TRANSACTION",
    "rows": []
  },
  {
    "step": 9,
    "elapsed_ms": 13.095,
    "actor": "A",
    "action": "submit",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1"
  },
  {
    "step": 10,
    "elapsed_ms": 13.815,
    "actor": "A",
    "action": "returned",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1",
    "rows": [
      {
        "n": 2
      }
    ]
  },
  {
    "step": 11,
    "elapsed_ms": 13.818,
    "actor": "B",
    "action": "submit",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1"
  },
  {
    "step": 12,
    "elapsed_ms": 14.337,
    "actor": "B",
    "action": "returned",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1",
    "rows": [
      {
        "n": 2
      }
    ]
  },
  {
    "step": 13,
    "elapsed_ms": 14.339,
    "actor": "coordinator",
    "action": "barrier: both initial counts completed before writes"
  },
  {
    "step": 14,
    "elapsed_ms": 14.434,
    "actor": "B",
    "action": "submit",
    "sql": "UPDATE oncall_roster SET on_call=0 WHERE shift_id=1 AND doctor_id=%s AND on_call=1",
    "parameters": [
      2
    ]
  },
  {
    "step": 15,
    "elapsed_ms": 14.466,
    "actor": "A",
    "action": "submit",
    "sql": "UPDATE oncall_roster SET on_call=0 WHERE shift_id=1 AND doctor_id=%s AND on_call=1",
    "parameters": [
      1
    ]
  },
  {
    "step": 16,
    "elapsed_ms": 15.365,
    "actor": "A",
    "action": "returned",
    "sql": "UPDATE oncall_roster SET on_call=0 WHERE shift_id=1 AND doctor_id=%s AND on_call=1",
    "rows": [],
    "parameters": [
      1
    ]
  },
  {
    "step": 17,
    "elapsed_ms": 15.368,
    "actor": "A",
    "action": "submit",
    "sql": "COMMIT"
  },
  {
    "step": 18,
    "elapsed_ms": 15.414,
    "actor": "B",
    "action": "returned",
    "sql": "UPDATE oncall_roster SET on_call=0 WHERE shift_id=1 AND doctor_id=%s AND on_call=1",
    "rows": [],
    "parameters": [
      2
    ]
  },
  {
    "step": 19,
    "elapsed_ms": 15.424,
    "actor": "B",
    "action": "submit",
    "sql": "COMMIT"
  },
  {
    "step": 20,
    "elapsed_ms": 17.547,
    "actor": "A",
    "action": "returned",
    "sql": "COMMIT",
    "rows": []
  },
  {
    "step": 21,
    "elapsed_ms": 18.433,
    "actor": "B",
    "action": "returned",
    "sql": "COMMIT",
    "rows": []
  }
]
REPEATABLE READ / late_guard / 剩余 0

独立终值与模型判断

{
  "final_rows": [
    {
      "doctor_id": 1,
      "on_call": 0
    },
    {
      "doctor_id": 2,
      "on_call": 0
    }
  ],
  "oracle": {
    "on_call_count": 0,
    "invariant_holds": false,
    "serially_reachable": false,
    "allowed_serial_states": [
      [
        0,
        1
      ],
      [
        1,
        0
      ]
    ]
  },
  "decisions": {
    "A": {
      "doctor_id": 1,
      "observed_count": 2,
      "approved": true,
      "outcome": "committed"
    },
    "B": {
      "doctor_id": 2,
      "observed_count": 2,
      "approved": true,
      "outcome": "committed"
    }
  }
}
actortableindexmodestatus
Aoncall_guardPRIMARYX,REC_NOT_GAPGRANTED
Aoncall_guardNoneIXGRANTED
Boncall_guardPRIMARYX,REC_NOT_GAPWAITING
Boncall_guardNoneIXGRANTED

实际执行时间线,含 SQL 参数

[
  {
    "step": 1,
    "elapsed_ms": 6.902,
    "actor": "A",
    "action": "submit",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ"
  },
  {
    "step": 2,
    "elapsed_ms": 7.487,
    "actor": "A",
    "action": "returned",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ",
    "rows": []
  },
  {
    "step": 3,
    "elapsed_ms": 7.49,
    "actor": "A",
    "action": "submit",
    "sql": "START TRANSACTION"
  },
  {
    "step": 4,
    "elapsed_ms": 8.008,
    "actor": "A",
    "action": "returned",
    "sql": "START TRANSACTION",
    "rows": []
  },
  {
    "step": 5,
    "elapsed_ms": 8.01,
    "actor": "B",
    "action": "submit",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ"
  },
  {
    "step": 6,
    "elapsed_ms": 8.545,
    "actor": "B",
    "action": "returned",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ",
    "rows": []
  },
  {
    "step": 7,
    "elapsed_ms": 8.547,
    "actor": "B",
    "action": "submit",
    "sql": "START TRANSACTION"
  },
  {
    "step": 8,
    "elapsed_ms": 9.054,
    "actor": "B",
    "action": "returned",
    "sql": "START TRANSACTION",
    "rows": []
  },
  {
    "step": 9,
    "elapsed_ms": 9.058,
    "actor": "A",
    "action": "submit",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1"
  },
  {
    "step": 10,
    "elapsed_ms": 9.794,
    "actor": "A",
    "action": "returned",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1",
    "rows": [
      {
        "n": 2
      }
    ]
  },
  {
    "step": 11,
    "elapsed_ms": 9.796,
    "actor": "B",
    "action": "submit",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1"
  },
  {
    "step": 12,
    "elapsed_ms": 10.817,
    "actor": "B",
    "action": "returned",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1",
    "rows": [
      {
        "n": 2
      }
    ]
  },
  {
    "step": 13,
    "elapsed_ms": 10.82,
    "actor": "coordinator",
    "action": "barrier: both initial counts completed before writes"
  },
  {
    "step": 14,
    "elapsed_ms": 10.822,
    "actor": "A",
    "action": "submit",
    "sql": "SELECT shift_id FROM oncall_guard WHERE shift_id=1 FOR UPDATE"
  },
  {
    "step": 15,
    "elapsed_ms": 11.438,
    "actor": "A",
    "action": "returned",
    "sql": "SELECT shift_id FROM oncall_guard WHERE shift_id=1 FOR UPDATE",
    "rows": [
      {
        "shift_id": 1
      }
    ]
  },
  {
    "step": 16,
    "elapsed_ms": 11.53,
    "actor": "B",
    "action": "submit",
    "sql": "SELECT shift_id FROM oncall_guard WHERE shift_id=1 FOR UPDATE"
  },
  {
    "step": 17,
    "elapsed_ms": 14.814,
    "actor": "observer",
    "action": "barrier: observed lock wait",
    "waiting": "B",
    "blocking": "A"
  },
  {
    "step": 18,
    "elapsed_ms": 14.819,
    "actor": "coordinator",
    "action": "barrier: release A only after observed B→A wait"
  },
  {
    "step": 19,
    "elapsed_ms": 14.821,
    "actor": "A",
    "action": "submit",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1"
  },
  {
    "step": 20,
    "elapsed_ms": 16.029,
    "actor": "A",
    "action": "returned",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1",
    "rows": [
      {
        "n": 2
      }
    ]
  },
  {
    "step": 21,
    "elapsed_ms": 16.034,
    "actor": "A",
    "action": "submit",
    "sql": "UPDATE oncall_roster SET on_call=0 WHERE shift_id=1 AND doctor_id=%s AND on_call=1",
    "parameters": [
      1
    ]
  },
  {
    "step": 22,
    "elapsed_ms": 17.838,
    "actor": "A",
    "action": "returned",
    "sql": "UPDATE oncall_roster SET on_call=0 WHERE shift_id=1 AND doctor_id=%s AND on_call=1",
    "rows": [],
    "parameters": [
      1
    ]
  },
  {
    "step": 23,
    "elapsed_ms": 17.842,
    "actor": "A",
    "action": "submit",
    "sql": "COMMIT"
  },
  {
    "step": 24,
    "elapsed_ms": 19.769,
    "actor": "A",
    "action": "returned",
    "sql": "COMMIT",
    "rows": []
  },
  {
    "step": 25,
    "elapsed_ms": 19.83,
    "actor": "B",
    "action": "returned",
    "sql": "SELECT shift_id FROM oncall_guard WHERE shift_id=1 FOR UPDATE",
    "rows": [
      {
        "shift_id": 1
      }
    ]
  },
  {
    "step": 26,
    "elapsed_ms": 19.837,
    "actor": "B",
    "action": "submit",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1"
  },
  {
    "step": 27,
    "elapsed_ms": 20.487,
    "actor": "B",
    "action": "returned",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1",
    "rows": [
      {
        "n": 2
      }
    ]
  },
  {
    "step": 28,
    "elapsed_ms": 20.49,
    "actor": "B",
    "action": "submit",
    "sql": "UPDATE oncall_roster SET on_call=0 WHERE shift_id=1 AND doctor_id=%s AND on_call=1",
    "parameters": [
      2
    ]
  },
  {
    "step": 29,
    "elapsed_ms": 21.136,
    "actor": "B",
    "action": "returned",
    "sql": "UPDATE oncall_roster SET on_call=0 WHERE shift_id=1 AND doctor_id=%s AND on_call=1",
    "rows": [],
    "parameters": [
      2
    ]
  },
  {
    "step": 30,
    "elapsed_ms": 21.138,
    "actor": "B",
    "action": "submit",
    "sql": "COMMIT"
  },
  {
    "step": 31,
    "elapsed_ms": 22.756,
    "actor": "B",
    "action": "returned",
    "sql": "COMMIT",
    "rows": []
  }
]
REPEATABLE READ / guard_first / 剩余 1

独立终值与模型判断

{
  "final_rows": [
    {
      "doctor_id": 1,
      "on_call": 0
    },
    {
      "doctor_id": 2,
      "on_call": 1
    }
  ],
  "oracle": {
    "on_call_count": 1,
    "invariant_holds": true,
    "serially_reachable": true,
    "allowed_serial_states": [
      [
        0,
        1
      ],
      [
        1,
        0
      ]
    ]
  },
  "decisions": {
    "A": {
      "doctor_id": 1,
      "observed_count": 2,
      "approved": true,
      "outcome": "committed"
    },
    "B": {
      "doctor_id": 2,
      "observed_count": 1,
      "approved": false,
      "outcome": "committed"
    }
  }
}
actortableindexmodestatus
Aoncall_guardPRIMARYX,REC_NOT_GAPGRANTED
Aoncall_guardNoneIXGRANTED
Boncall_guardPRIMARYX,REC_NOT_GAPWAITING
Boncall_guardNoneIXGRANTED

实际执行时间线,含 SQL 参数

[
  {
    "step": 1,
    "elapsed_ms": 7.752,
    "actor": "A",
    "action": "submit",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ"
  },
  {
    "step": 2,
    "elapsed_ms": 8.148,
    "actor": "A",
    "action": "returned",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ",
    "rows": []
  },
  {
    "step": 3,
    "elapsed_ms": 8.15,
    "actor": "A",
    "action": "submit",
    "sql": "START TRANSACTION"
  },
  {
    "step": 4,
    "elapsed_ms": 8.564,
    "actor": "A",
    "action": "returned",
    "sql": "START TRANSACTION",
    "rows": []
  },
  {
    "step": 5,
    "elapsed_ms": 8.566,
    "actor": "B",
    "action": "submit",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ"
  },
  {
    "step": 6,
    "elapsed_ms": 9.101,
    "actor": "B",
    "action": "returned",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ",
    "rows": []
  },
  {
    "step": 7,
    "elapsed_ms": 9.104,
    "actor": "B",
    "action": "submit",
    "sql": "START TRANSACTION"
  },
  {
    "step": 8,
    "elapsed_ms": 9.499,
    "actor": "B",
    "action": "returned",
    "sql": "START TRANSACTION",
    "rows": []
  },
  {
    "step": 9,
    "elapsed_ms": 9.502,
    "actor": "A",
    "action": "submit",
    "sql": "SELECT shift_id FROM oncall_guard WHERE shift_id=1 FOR UPDATE"
  },
  {
    "step": 10,
    "elapsed_ms": 10.003,
    "actor": "A",
    "action": "returned",
    "sql": "SELECT shift_id FROM oncall_guard WHERE shift_id=1 FOR UPDATE",
    "rows": [
      {
        "shift_id": 1
      }
    ]
  },
  {
    "step": 11,
    "elapsed_ms": 10.101,
    "actor": "B",
    "action": "submit",
    "sql": "SELECT shift_id FROM oncall_guard WHERE shift_id=1 FOR UPDATE"
  },
  {
    "step": 12,
    "elapsed_ms": 11.833,
    "actor": "observer",
    "action": "barrier: observed lock wait",
    "waiting": "B",
    "blocking": "A"
  },
  {
    "step": 13,
    "elapsed_ms": 11.836,
    "actor": "coordinator",
    "action": "barrier: release A only after observed B→A wait"
  },
  {
    "step": 14,
    "elapsed_ms": 11.838,
    "actor": "A",
    "action": "submit",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1"
  },
  {
    "step": 15,
    "elapsed_ms": 12.365,
    "actor": "A",
    "action": "returned",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1",
    "rows": [
      {
        "n": 2
      }
    ]
  },
  {
    "step": 16,
    "elapsed_ms": 12.369,
    "actor": "A",
    "action": "submit",
    "sql": "UPDATE oncall_roster SET on_call=0 WHERE shift_id=1 AND doctor_id=%s AND on_call=1",
    "parameters": [
      1
    ]
  },
  {
    "step": 17,
    "elapsed_ms": 12.953,
    "actor": "A",
    "action": "returned",
    "sql": "UPDATE oncall_roster SET on_call=0 WHERE shift_id=1 AND doctor_id=%s AND on_call=1",
    "rows": [],
    "parameters": [
      1
    ]
  },
  {
    "step": 18,
    "elapsed_ms": 12.956,
    "actor": "A",
    "action": "submit",
    "sql": "COMMIT"
  },
  {
    "step": 19,
    "elapsed_ms": 14.716,
    "actor": "A",
    "action": "returned",
    "sql": "COMMIT",
    "rows": []
  },
  {
    "step": 20,
    "elapsed_ms": 14.802,
    "actor": "B",
    "action": "returned",
    "sql": "SELECT shift_id FROM oncall_guard WHERE shift_id=1 FOR UPDATE",
    "rows": [
      {
        "shift_id": 1
      }
    ]
  },
  {
    "step": 21,
    "elapsed_ms": 14.81,
    "actor": "B",
    "action": "submit",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1"
  },
  {
    "step": 22,
    "elapsed_ms": 15.634,
    "actor": "B",
    "action": "returned",
    "sql": "SELECT COUNT(*) AS n FROM oncall_roster WHERE shift_id=1 AND on_call=1",
    "rows": [
      {
        "n": 1
      }
    ]
  },
  {
    "step": 23,
    "elapsed_ms": 15.639,
    "actor": "B",
    "action": "submit",
    "sql": "COMMIT"
  },
  {
    "step": 24,
    "elapsed_ms": 16.269,
    "actor": "B",
    "action": "returned",
    "sql": "COMMIT",
    "rows": []
  }
]
REPEATABLE READ / locking_roster / 剩余 1

独立终值与模型判断

{
  "final_rows": [
    {
      "doctor_id": 1,
      "on_call": 0
    },
    {
      "doctor_id": 2,
      "on_call": 1
    }
  ],
  "oracle": {
    "on_call_count": 1,
    "invariant_holds": true,
    "serially_reachable": true,
    "allowed_serial_states": [
      [
        0,
        1
      ],
      [
        1,
        0
      ]
    ]
  },
  "decisions": {
    "A": {
      "doctor_id": 1,
      "observed_count": 2,
      "approved": true,
      "outcome": "committed"
    },
    "B": {
      "doctor_id": 2,
      "observed_count": 1,
      "approved": false,
      "outcome": "committed"
    }
  }
}
actortableindexmodestatus
Aoncall_rosterPRIMARYXGRANTED
Aoncall_rosterPRIMARYXGRANTED
Aoncall_rosterPRIMARYXGRANTED
Aoncall_rosterNoneIXGRANTED
Boncall_rosterPRIMARYXWAITING
Boncall_rosterNoneIXGRANTED

实际执行时间线,含 SQL 参数

[
  {
    "step": 1,
    "elapsed_ms": 6.286,
    "actor": "A",
    "action": "submit",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ"
  },
  {
    "step": 2,
    "elapsed_ms": 6.803,
    "actor": "A",
    "action": "returned",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ",
    "rows": []
  },
  {
    "step": 3,
    "elapsed_ms": 6.807,
    "actor": "A",
    "action": "submit",
    "sql": "START TRANSACTION"
  },
  {
    "step": 4,
    "elapsed_ms": 7.317,
    "actor": "A",
    "action": "returned",
    "sql": "START TRANSACTION",
    "rows": []
  },
  {
    "step": 5,
    "elapsed_ms": 7.323,
    "actor": "B",
    "action": "submit",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ"
  },
  {
    "step": 6,
    "elapsed_ms": 7.828,
    "actor": "B",
    "action": "returned",
    "sql": "SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ",
    "rows": []
  },
  {
    "step": 7,
    "elapsed_ms": 7.831,
    "actor": "B",
    "action": "submit",
    "sql": "START TRANSACTION"
  },
  {
    "step": 8,
    "elapsed_ms": 8.385,
    "actor": "B",
    "action": "returned",
    "sql": "START TRANSACTION",
    "rows": []
  },
  {
    "step": 9,
    "elapsed_ms": 8.389,
    "actor": "A",
    "action": "submit",
    "sql": "SELECT doctor_id FROM oncall_roster WHERE shift_id=1 AND on_call=1 ORDER BY doctor_id FOR UPDATE"
  },
  {
    "step": 10,
    "elapsed_ms": 9.232,
    "actor": "A",
    "action": "returned",
    "sql": "SELECT doctor_id FROM oncall_roster WHERE shift_id=1 AND on_call=1 ORDER BY doctor_id FOR UPDATE",
    "rows": [
      {
        "doctor_id": 1
      },
      {
        "doctor_id": 2
      }
    ]
  },
  {
    "step": 11,
    "elapsed_ms": 9.334,
    "actor": "B",
    "action": "submit",
    "sql": "SELECT doctor_id FROM oncall_roster WHERE shift_id=1 AND on_call=1 ORDER BY doctor_id FOR UPDATE"
  },
  {
    "step": 12,
    "elapsed_ms": 11.487,
    "actor": "observer",
    "action": "barrier: observed lock wait",
    "waiting": "B",
    "blocking": "A"
  },
  {
    "step": 13,
    "elapsed_ms": 11.491,
    "actor": "coordinator",
    "action": "barrier: release A only after observed B→A wait"
  },
  {
    "step": 14,
    "elapsed_ms": 11.494,
    "actor": "A",
    "action": "submit",
    "sql": "UPDATE oncall_roster SET on_call=0 WHERE shift_id=1 AND doctor_id=%s AND on_call=1",
    "parameters": [
      1
    ]
  },
  {
    "step": 15,
    "elapsed_ms": 12.197,
    "actor": "A",
    "action": "returned",
    "sql": "UPDATE oncall_roster SET on_call=0 WHERE shift_id=1 AND doctor_id=%s AND on_call=1",
    "rows": [],
    "parameters": [
      1
    ]
  },
  {
    "step": 16,
    "elapsed_ms": 12.201,
    "actor": "A",
    "action": "submit",
    "sql": "COMMIT"
  },
  {
    "step": 17,
    "elapsed_ms": 14.238,
    "actor": "A",
    "action": "returned",
    "sql": "COMMIT",
    "rows": []
  },
  {
    "step": 18,
    "elapsed_ms": 14.292,
    "actor": "B",
    "action": "returned",
    "sql": "SELECT doctor_id FROM oncall_roster WHERE shift_id=1 AND on_call=1 ORDER BY doctor_id FOR UPDATE",
    "rows": [
      {
        "doctor_id": 2
      }
    ]
  },
  {
    "step": 19,
    "elapsed_ms": 14.296,
    "actor": "B",
    "action": "submit",
    "sql": "COMMIT"
  },
  {
    "step": 20,
    "elapsed_ms": 14.759,
    "actor": "B",
    "action": "returned",
    "sql": "COMMIT",
    "rows": []
  }
]

理论与实现边界

CMU/MIT 用于理解调度、2PL 与多版本。本实验验证显式 START TRANSACTION 内的具体 MySQL 8.4 语句,不代表全部 InnoDB 读取都遵循严格 2PL,也不代表所有 RR 历史都可串行化。不需要 API key、模型、向量插件或外部数据库。

具体讲次与阅读映射 → · MySQL 8.4 consistent reads · MySQL 8.4 locking reads