fix(approval): 版本号唯一键兜底 + 取号改当前读防并发重复
- V12 迁移:先重排存量重复 (order_type, ref_id) 分组的 version_no (V11 把存量一律置 1,而 V11 前重提是新建行),再加 uk_approval_orders_order_type_ref_version;只重排真有重复的分组, 避免改动前端已展示过的历史版本号 - _next_version 改锁读(select version_no ... FOR UPDATE,最大值在 Python 侧算):请求级鉴权的普通 SELECT 已把 REPEATABLE READ 快照 锚定在请求开始时刻,原 MAX 快照读在并发下会算出同一版本号; 聚合 + FOR UPDATE 为 MySQL 明确禁止,故不锁聚合结果 - 编辑与月结提交路径把 1062 收敛为 400「提交冲突(版本号生成重复), 请重试」,其余完整性错误原样上抛;submit_order 内不 catch/rollback - 驳回清空方案的过时注释改为 V11 起的 append-only 语义(置历史不删行) - init-dev.sql 同步唯一键与 alembic_version 7f4f7b918bc4,导出 V12 SQL - 测试:集成 +5(锁读 SQL 形态、两会话快照回归、唯一键 1062、冲突 400、 正常递增)+ 单元 +1;工作台假审批单改用不同 ref_id 适配唯一键 - 全量回归 897 passed;ruff 与前端 type-check 绿 Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
1 parent
694d21d1fd
commit
9964281c14
12 files changed
+398
-42
No files matched your search
@@ -96,6 +96,20 @@ class TestNamingConvention:
|
||||
for fk in table.foreign_keys:
|
||||
assert fk.constraint.name.startswith(f"fk_{table.name}_"), fk.constraint.name
|
||||
|
||||
def test_审批单版本号唯一键覆盖三列(self) -> None:
|
||||
"""并发提单算重版本号时由 DB 兜底(应用层取号走锁读,见
|
||||
approval_service._next_version);约束名必须与迁移 DDL 严格一致,
|
||||
否则 alembic autogenerate 会误判成「约束缺失/多余」。"""
|
||||
table = Base.metadata.tables["approval_orders"]
|
||||
uks = [c for c in table.constraints if c.__class__.__name__ == "UniqueConstraint"]
|
||||
hit = [
|
||||
c
|
||||
for c in uks
|
||||
if {col.name for col in c.columns} == {"order_type", "ref_id", "version_no"}
|
||||
]
|
||||
assert hit, "审批单缺 (order_type, ref_id, version_no) 唯一键"
|
||||
assert hit[0].name == "uk_approval_orders_order_type_ref_version"
|
||||
|
||||
|
||||
class TestComments:
|
||||
"""规范红线要求中文 COMMENT。"""
|
||||
|
||||
Reference in new issue
Block a user