Files
OnlineJudge/problem/services.py
yuetsh db104ac091 fix(problem): resolve_tags 的 create 包一层 atomic
外层若在事务里,IntegrityError 会中止整个事务,导致回查抛
TransactionManagementError。当前未开 ATOMIC_REQUESTS 所以还没触发,
但仓库多处用了 transaction.atomic(),属于随时会踩的坑。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-05 04:29:48 -06:00

56 lines
1.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from django.core.cache import cache
from django.db import IntegrityError, transaction
from utils.constants import CacheKey
from .models import ProblemTag
def clear_tag_cache():
"""标签列表接口按 keyword 分键缓存,标签一变就整批清掉"""
cache.delete_pattern(f"{CacheKey.problem_tags}:*")
def find_tags(names):
"""按名字大小写不敏感查已有标签,查不到就跳过,不创建"""
tags = []
seen = set()
for raw in names:
name = (raw or "").strip()
if not name or name.lower() in seen:
continue
seen.add(name.lower())
tag = ProblemTag.objects.filter(name__iexact=name).first()
if tag is not None:
tags.append(tag)
return tags
def resolve_tags(names):
"""把前端传来的标签名解析成 ProblemTag去空格、大小写不敏感复用已有标签没有才新建"""
tags = []
seen = set()
created = False
for raw in names:
name = (raw or "").strip()
if not name or name.lower() in seen:
continue
seen.add(name.lower())
tag = ProblemTag.objects.filter(name__iexact=name).first()
if tag is None:
try:
# 包一层 atomic外层若在事务里IntegrityError 会中止整个事务,
# 导致下面的回查抛 TransactionManagementError
with transaction.atomic():
tag = ProblemTag.objects.create(name=name)
created = True
except IntegrityError:
# 并发下另一个请求刚建好同名标签,回查复用
tag = ProblemTag.objects.filter(name__iexact=name).first()
if tag is None:
continue
tags.append(tag)
if created:
clear_tag_cache()
return tags