fix(rating): 区间重叠判定改用锁定读取,防并发重叠双提交
先查后写无锁时,两管理员并发提交重叠区间互判不重叠而双双入库 (区间重叠无唯一键可拦,同一总分命中多等级且结果取决于插入顺序); 判重叠的 list_all 加 for_update 锁全表行串行化并发判定,只读直出 list_grades 不加锁。SQL 形态用例锁定两条口径。 Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
1 parent
e6c2c71d1b
commit
c2b462df3b
3 files changed
+31
-3
No files matched your search
@@ -98,6 +98,27 @@ class TestAuth:
|
||||
assert resp.status_code == 401, resp.text
|
||||
|
||||
|
||||
class TestOverlapGuardLock:
|
||||
"""区间重叠判定的并发防线:判重叠的 list_all 必须带 FOR UPDATE。
|
||||
|
||||
区间重叠无唯一键可拦(名称才有 uk),无锁时两管理员并发提交重叠区间
|
||||
会互判不重叠而双双入库。双连接真并发需线程与锁等待控制,此处锁定
|
||||
SQL 形态两条口径:for_update 编译产物含 FOR UPDATE、只读直出不含。
|
||||
"""
|
||||
|
||||
def test_判重叠查询带FOR_UPDATE_只读直出不带(self) -> None:
|
||||
from app.models import CustomerRatingGrade
|
||||
|
||||
locked = (
|
||||
select(CustomerRatingGrade)
|
||||
.order_by(CustomerRatingGrade.sort_order, CustomerRatingGrade.id)
|
||||
.with_for_update()
|
||||
)
|
||||
assert "FOR UPDATE" in str(locked.compile())
|
||||
plain = select(CustomerRatingGrade).order_by(CustomerRatingGrade.sort_order)
|
||||
assert "FOR UPDATE" not in str(plain.compile())
|
||||
|
||||
|
||||
class TestList:
|
||||
"""列表直出种子基线:判定表是前端评级计算器的唯一数据源。"""
|
||||
|
||||
|
||||
Reference in new issue
Block a user