Fix SQLite lock errors on /api/stats under concurrent writes.

Retry stats cache commits, serialize refresh, and fall back to read-only compute so the stats API does not return 500 when the database is briefly locked.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-26 12:23:33 +08:00
parent d3955309d9
commit 508d85a282
3 changed files with 50 additions and 12 deletions
+23
View File
@@ -47,3 +47,26 @@ def execute_retry(
if last_exc:
raise last_exc
raise sqlite3.OperationalError("database is locked")
def commit_retry(
conn: sqlite3.Connection,
*,
retries: int = 6,
base_delay: float = 0.05,
) -> None:
"""遇 database is locked 时短暂退避重试 commit。"""
last_exc: Exception | None = None
for attempt in range(retries):
try:
conn.commit()
return
except sqlite3.OperationalError as exc:
if "locked" not in str(exc).lower():
raise
last_exc = exc
if attempt < retries - 1:
time.sleep(base_delay * (attempt + 1))
if last_exc:
raise last_exc
raise sqlite3.OperationalError("database is locked")