Player Module Writer Lock Hierarchy¶
概念概覽
Lock Ordering(已定案)¶
核心知識¶
Lock Ordering(已定案)¶
Step 0: player_mutation_idempotency — INSERT ON CONFLICT DO NOTHING
Step 1: players row — SELECT ... FOR UPDATE (per-user serialization)
Step 2: player_inventory — inventory locks
Step 3: player_resources — resource locks
Step 4: player_resource_pools — pool locks
Step 5: audit log — append only
所有 player module 的 mutation writer 必須遵守此順序,違反者有 deadlock 風險。
Writer 覆蓋表(Step 6e)¶
需要加 per-user row lock 的非 executor 路徑(Step 6e 補強):
| Writer | 位置 | 說明 |
|---|---|---|
addStaminaDetailed |
player_service.go:1811 | admin stamina |
adminSetResource |
player_service.go:2233 | admin resource set |
addCurrencyAmountDetailed |
inventory_service | currency |
ConsumeStamina |
inventory_service:1671 | stamina consume |
cleanupExpiredForUser |
— | per-user cleanup |
文件責任邊界¶
- mutation-pipeline 文件:封口 player module 內所有 writer 的 lock contract
- sticker/activity 文件:負責 cross-module ordering(
player_sticker_season_progress FOR UPDATE) - cross-module lock hierarchy:不屬於 mutation-pipeline 文件,由各自整合方負責
效能考量與 1M CCU 評估¶
AcquireRowLock 對 1M CCU 的影響需要對齊: - 現有 infra:Aurora writer db.r6g.4xlarge,reader 3x db.r6g.2xlarge,RDS Proxy enabled - production sign-off 仍需 staged load test 驗證 DB acquire wait p99
經驗教訓¶
-
global lock hierarchy 不需要整份塞進 mutation-pipeline 文件,文件只需要 publish 自己的 lock contract
-
admin 與 cleanup 路徑容易被忽略,但它們游離在 executor lock contract 外就是設計債
-
cross-module lock ordering(如 sticker/activity)應由整合方負責,不要讓 mutation-pipeline 文件承擔全域排序責任
常見陷阱¶
-
Sticker/Activity 已定案 player_sticker_season_progress FOR UPDATE,若與 players row lock 沒有全域排序,跨模組 deadlock 風險存在
-
只在 inventory 路徑加鎖,忽略 admin stamina/resource writer,是常見的 lock coverage 漏洞
最佳實踐¶
-
每個 player module mutation writer 必須先取得 players row FOR UPDATE,再操作下游表
-
lock 覆蓋表要明確列出「writer/lock coverage」,不能只覆蓋 happy path executor,admin/cleanup/resource writer 同樣需要納入
相關概念¶
來源 Sessions¶
| 日期 | Session | 貢獻摘要 |
|---|---|---|
| 2026-04-14 | a7a343a3-2a2d-4fde-8057-503f23ef22e2 | 確立 MatchRPG Player Module 的完整 writer lock 覆蓋順序,並識別 admin/cleanup 路徑是 sign-off P0 缺口 |