91 lines
4.9 KiB
JSON
91 lines
4.9 KiB
JSON
{
|
||
"summary": [
|
||
{
|
||
"name": "pbl_entity_state",
|
||
"title": "实体当前状态(乐观锁版本表)",
|
||
"primary": [
|
||
"id"
|
||
],
|
||
"catelog": "relation",
|
||
"comment": "PBL 实体当前状态表(world_sync 侧,M11b-2 新增)。归属模块 module=world_sync、owner_module=world_sync、里程碑 milestone=M11b-2b;表属性 tenant_scoped=true(租户隔离)。保存世界内实体的最新完整状态快照,state_version 为乐观锁版本号(每次成功写入 +1),用于防止并发覆盖(丢失更新)。【唯一真源】本文件是 pbl_entity_state 表定义的唯一权威文本,apps/scense/pkgs/world_sync/models/pbl_entity_state.json 只是由 scripts/sync_models_to_app.py(或 cp)从本文件同步出的打包镜像,禁止手工双写,二者 sha256 必须相同(由 scripts/m11b2_selftest.py 机械断言)。【主键与唯一性】规范主键 id 为 str(32)(应用层生成 uuid4().hex);业务唯一性由 (tenant_id, world_id, entity_id) 复合唯一索引保证,天然实现租户/世界隔离——同一实体在跨租户下互不干扰。【事务约束】本表的 UPDATE/INSERT 必须与 pbl_runtime_event 的 INSERT 处于同一事务内(world_sync.pbl_runtime_tx.write_event_with_state),任一失败整事务回滚;禁止脱离事务单独更新本表。【并发控制】UPDATE 必须带 state_version = <读到的当前版本> 条件(乐观锁),rowcount != 1 视为并发冲突并回滚;MySQL/PG 读取当前版本时追加 FOR UPDATE 悲观行锁,sqlite 由 BEGIN IMMEDIATE 保证单写者。【列真源】fields 与 world_sync/pbl_runtime_sql.py 的 STATE_COLUMNS 及 pbl_runtime_tx.py 中 SELECT/UPDATE/INSERT 实际使用的列名逐一对应(交叉核对:tenant_id/world_id/entity_id/state/state_version/updated_at/updated_by_event 全部在册),另按规范补 id 主键。【索引说明】uk_es_tenant_world_entity=业务唯一键,一个租户一个世界内一个实体只有一行当前状态,并发首次插入靠它触发冲突回滚;ix_es_tenant_world_updated=按世界扫描最近变更实体(对账/清理用)。【与 pbl_runtime_ext 的差异】modules/pbl_runtime_ext/models/pbl_entity_state.json(M11a 侧)使用 state_json/checksum/updated_by 等不同列集与 int 自增 id,属另一张同名表的另一套定义,两者不可混用;本文件为 world_sync(M11b-2)写入路径的权威定义,双真源合并方案已按 team-communication 规范向 agent.pm 冒泡请求裁决(见交付摘要冒泡单据)。【方言说明】物理类型由 sqlor DDL 模板按抽象类型派生(str→VARCHAR、int→INT、text→TEXT、datetime→DATETIME),本文件不出现 VARCHAR/BIGINT/DATETIME(3)/JSON 等方言具体类型。【键白名单】summary 仅含 name/title/primary/catelog/comment;fields 仅含 name/title/type/length/dec/nullable/default(说明文字一律写进 title,DDL 模板按 title 渲染 COMMENT);indexes 仅含 name/idxtype/idxfields;根键仅 summary/fields/indexes/codes 四段式。"
|
||
}
|
||
],
|
||
"fields": [
|
||
{
|
||
"name": "id",
|
||
"title": "主键ID(str32,应用层生成uuid4().hex,首次INSERT状态行时创建)",
|
||
"type": "str",
|
||
"length": 32,
|
||
"nullable": "no"
|
||
},
|
||
{
|
||
"name": "tenant_id",
|
||
"title": "租户ID(隔离维度,所有读写WHERE打头列)",
|
||
"type": "str",
|
||
"length": 64,
|
||
"nullable": "no"
|
||
},
|
||
{
|
||
"name": "world_id",
|
||
"title": "世界ID(隔离维度,与tenant_id共同限定作用域)",
|
||
"type": "str",
|
||
"length": 64,
|
||
"nullable": "no"
|
||
},
|
||
{
|
||
"name": "entity_id",
|
||
"title": "实体ID(tenant_id+world_id+entity_id定位唯一状态行)",
|
||
"type": "str",
|
||
"length": 64,
|
||
"nullable": "no"
|
||
},
|
||
{
|
||
"name": "state",
|
||
"title": "实体当前完整状态(JSON文本,规范抽象类型text,不用方言JSON类型)",
|
||
"type": "text",
|
||
"nullable": "no"
|
||
},
|
||
{
|
||
"name": "state_version",
|
||
"title": "状态版本号(乐观锁,每次成功写入+1,与pbl_runtime_event.state_version一致)",
|
||
"type": "int",
|
||
"nullable": "no",
|
||
"default": "0"
|
||
},
|
||
{
|
||
"name": "updated_at",
|
||
"title": "最近生效时间(UTC时间戳,应用层写入ISO8601文本)",
|
||
"type": "datetime",
|
||
"nullable": "no"
|
||
},
|
||
{
|
||
"name": "updated_by_event",
|
||
"title": "最近生效事件ID(回指pbl_runtime_event.event_id业务键)",
|
||
"type": "str",
|
||
"length": 64,
|
||
"nullable": "yes"
|
||
}
|
||
],
|
||
"indexes": [
|
||
{
|
||
"name": "uk_es_tenant_world_entity",
|
||
"idxtype": "unique",
|
||
"idxfields": [
|
||
"tenant_id",
|
||
"world_id",
|
||
"entity_id"
|
||
]
|
||
},
|
||
{
|
||
"name": "ix_es_tenant_world_updated",
|
||
"idxtype": "index",
|
||
"idxfields": [
|
||
"tenant_id",
|
||
"world_id",
|
||
"updated_at"
|
||
]
|
||
}
|
||
],
|
||
"codes": []
|
||
}
|