fix(db): 每请求独立 AsyncSession(根除并发 500)

- get_db 由「返回 app.state.db 单例」改为「每请求各建一个 Database 并在结束关闭」
- Database.__init__ 复用按 url 缓存的共享异步引擎(_shared_engine),避免每请求重建引擎
- 修复 GET /auth/me、/admin/* 并发时 sqlalchemy.exc.InvalidRequestError: concurrent operations are not permitted(同一 AsyncSession 被并发请求复用)
- 对齐 park 子应用 _carrier_db 的每请求 Database 模式

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Pine
2026-08-27 14:17:55 +08:00
parent 873a70a095
commit 7ec9b8fd8a
2 changed files with 32 additions and 6 deletions
+12 -2
View File
@@ -23,8 +23,18 @@ def extract_bearer_token(request: Request) -> str:
return ""
def get_db(request: Request) -> Database:
return request.app.state.db
async def get_db():
"""每请求一个独立 Database/AsyncSession(绑定共享引擎)。
之前直接返回 app.state.db(单例 AsyncSession)被并发请求复用,会间歇报
``sqlalchemy.exc.InvalidRequestError: concurrent operations are not permitted``。
改为每请求各建一个 Database 并在请求结束关闭,根除该竞态。
"""
db = Database()
try:
yield db
finally:
await db.close()
async def _resolve_identity(user: dict, db: Database) -> dict: