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
@@ -156,7 +156,7 @@ def create_grade(
|
||||
new_min = _to_decimal(payload.min_score)
|
||||
new_max = _to_decimal(payload.max_score)
|
||||
_ensure_score_range(new_min, new_max)
|
||||
_ensure_no_overlap(rating_repository.list_all(session), new_min, new_max)
|
||||
_ensure_no_overlap(rating_repository.list_all(session, for_update=True), new_min, new_max)
|
||||
if rating_repository.get_by_name(session, payload.grade_name) is not None:
|
||||
raise BadRequestError("该等级名称已存在")
|
||||
|
||||
@@ -217,7 +217,7 @@ def update_grade(
|
||||
raise NotFoundError("评级等级不存在")
|
||||
|
||||
_ensure_no_overlap(
|
||||
rating_repository.list_all(session), new_min, new_max, exclude_id=grade_id
|
||||
rating_repository.list_all(session, for_update=True), new_min, new_max, exclude_id=grade_id
|
||||
)
|
||||
existed = rating_repository.get_by_name(session, payload.grade_name)
|
||||
if existed is not None and existed.id != grade_id:
|
||||
|
||||
Reference in new issue
Block a user