修复复盘列表与统计并行同步撞锁导致模拟盘加载失败。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-10-07 13:46:38 +08:00
parent cfcc0596ff
commit 2158a30179
5 changed files with 83 additions and 27 deletions
+32 -14
View File
@@ -66,21 +66,28 @@ def _safe_float(v: Any) -> Optional[float]:
def get_sync_state(conn: sqlite3.Connection, key: str) -> Optional[str]:
row = conn.execute(
"SELECT value FROM options_review_sync_state WHERE key=?", (key,)
).fetchone()
try:
row = conn.execute(
"SELECT value FROM options_review_sync_state WHERE key=?", (key,)
).fetchone()
except sqlite3.OperationalError:
return None
return str(row["value"]) if row and row["value"] is not None else None
def set_sync_state(conn: sqlite3.Connection, key: str, value: str) -> None:
conn.execute(
"""
INSERT INTO options_review_sync_state(key, value, updated_at)
VALUES (?, ?, ?)
ON CONFLICT(key) DO UPDATE SET value=excluded.value, updated_at=excluded.updated_at
""",
(key, value, _now_str()),
)
try:
conn.execute(
"""
INSERT INTO options_review_sync_state(key, value, updated_at)
VALUES (?, ?, ?)
ON CONFLICT(key) DO UPDATE SET value=excluded.value, updated_at=excluded.updated_at
""",
(key, value, _now_str()),
)
except sqlite3.OperationalError:
# 列表/统计并发刷新时可能撞锁;标记失败不阻断读列表
pass
def _purge_review_trade_by_key(conn: sqlite3.Connection, history_key: str) -> bool:
@@ -627,8 +634,16 @@ def ensure_local_review_synced(
repair_swapped_closed_at_signal_note,
)
ts_migrate = migrate_options_utc_wall_clock_to_app(conn)
note_swap = repair_swapped_closed_at_signal_note(conn)
ts_migrate: dict[str, Any] = {}
note_swap: dict[str, Any] = {}
try:
ts_migrate = migrate_options_utc_wall_clock_to_app(conn)
except Exception as e:
ts_migrate = {"ok": False, "msg": str(e)}
try:
note_swap = repair_swapped_closed_at_signal_note(conn)
except Exception as e:
note_swap = {"ok": False, "msg": str(e)}
if backfill_exchange_pnl and ex is not None:
try:
from lib.exchange.okx_options_lib import fetch_all_option_positions_history
@@ -640,7 +655,10 @@ def ensure_local_review_synced(
backfill_closed_options_realized_pnl_from_history(conn, hist)
except Exception:
pass
out = sync_all_review_sources(conn, ex=ex, from_exchange=False)
try:
out = sync_all_review_sources(conn, ex=ex, from_exchange=False)
except sqlite3.OperationalError as e:
out = {"ok": False, "msg": f"sync locked: {e}"}
if isinstance(out, dict):
out["ts_migrate"] = ts_migrate
out["note_swap"] = note_swap