🐛 修复数据库超时问题

This commit is contained in:
HibiKier
2025-08-22 02:43:19 +08:00
parent a63f26c3b6
commit 8d8cbf20c3
6 changed files with 70 additions and 11 deletions
+20
View File
@@ -16,6 +16,9 @@ from zhenxun.utils.enum import DbLockType
from .config import LOG_COMMAND, db_model
from .utils import with_db_timeout
total = {}
index = 0
class Model(TortoiseModel):
"""
@@ -221,12 +224,25 @@ class Model(TortoiseModel):
返回:
Self | None: 查询结果,如果不存在返回None
"""
global index, total
try:
if cls.__name__ == "BanConsole":
uid = kwargs.get("user_id")
if uid:
if uid not in total:
total[uid] = CacheRoot.cache_dict(f"DB_TEST_UID_{uid}", 10, int)
total[uid][str(index)] = "1"
index += 1
logger.info(
f"BanConsole 10秒内查询次数 uid: {uid}"
f" 查询次数: {len(total[uid])}"
)
# 先尝试使用 get_or_none 获取单个记录
try:
return await with_db_timeout(
cls.get_or_none(*args, using_db=using_db, **kwargs),
operation=f"{cls.__name__}.get_or_none",
source="DataBaseModel",
)
except MultipleObjectsReturned:
# 如果出现多个记录的情况,进行特殊处理
@@ -239,6 +255,7 @@ class Model(TortoiseModel):
records = await with_db_timeout(
cls.filter(*args, **kwargs).all(),
operation=f"{cls.__name__}.filter.all",
source="DataBaseModel",
)
if not records:
@@ -255,6 +272,7 @@ class Model(TortoiseModel):
await with_db_timeout(
record.delete(),
operation=f"{cls.__name__}.delete_duplicate",
source="DataBaseModel",
)
logger.info(
f"{cls.__name__} 删除重复记录:"
@@ -269,11 +287,13 @@ class Model(TortoiseModel):
return await with_db_timeout(
cls.filter(*args, **kwargs).order_by("-id").first(),
operation=f"{cls.__name__}.filter.order_by.first",
source="DataBaseModel",
)
# 如果没有 id 字段,则返回第一个记录
return await with_db_timeout(
cls.filter(*args, **kwargs).first(),
operation=f"{cls.__name__}.filter.first",
source="DataBaseModel",
)
except asyncio.TimeoutError:
logger.error(
+23 -1
View File
@@ -1,6 +1,7 @@
import asyncio
import time
from zhenxun.services.cache import CacheRoot
from zhenxun.services.log import logger
from .config import (
@@ -9,14 +10,35 @@ from .config import (
SLOW_QUERY_THRESHOLD,
)
cache = CacheRoot.cache_dict("DB_TEST", 10)
index = 0
total = {}
async def with_db_timeout(
coro, timeout: float = DB_TIMEOUT_SECONDS, operation: str | None = None
coro,
timeout: float = DB_TIMEOUT_SECONDS,
operation: str | None = None,
source: str | None = None,
):
"""带超时控制的数据库操作"""
global index, total, index2
start_time = time.time()
try:
if operation not in total:
total[operation] = CacheRoot.cache_dict(f"DB_TEST_{operation}", 10)
total[operation][str(index)] = "1"
index += 1
logger.info(f"当前数据库查询来源: {source}")
logger.info(
f"10秒内数据库查询次数 [{operation}]: {len(total[operation])}", "DB_TEST"
)
result = await asyncio.wait_for(coro, timeout=timeout)
cache[str(index)] = "1"
index += 1
elapsed = time.time() - start_time
if elapsed > SLOW_QUERY_THRESHOLD and operation:
logger.warning(f"慢查询: {operation} 耗时 {elapsed:.3f}s", LOG_COMMAND)