You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI+异步SQLAlchemy:请求后如何强制释放数据库连接?

FastAPI 异步SQLAlchemy 会话连接释放问题解决

你的问题核心是请求结束后数据库连接未正确归还到连接池,导致连接耗尽;而使用engine.dispose()会销毁整个连接池,造成请求卡顿。以下是正确的解决方案:

问题根源

原代码中使用async with async_session()包裹会话并yield,虽然上下文管理器理论上会自动关闭会话,但由于FastAPI依赖生成器的执行流程,会导致会话关闭逻辑延迟或未正确触发,连接无法及时归还到连接池,最终耗尽数据库连接上限。

正确实现方式

1. 配置引擎与会话工厂

添加连接池优化参数(可选但推荐),确保连接池健康:

async_db_url = f'postgresql+asyncpg://{db_user}:{db_pass}@{db_host}:{db_port}/{db_name}'
async_engine = create_async_engine(
    async_db_url,
    pool_pre_ping=True,  # 自动检测并丢弃无效连接
    pool_recycle=300,    # 回收闲置超过5分钟的连接
    pool_size=10,        # 连接池大小,根据数据库最大连接数调整
)
async_session = sessionmaker(
    async_engine,
    expire_on_commit=False,
    class_=AsyncSession,
    autocommit=False,
    autoflush=False,
)

2. 重写依赖函数

手动管理会话的生命周期,确保请求结束后连接归还到连接池:

from sqlalchemy.ext.asyncio import AsyncSession
from typing import AsyncGenerator

async def async_db_session() -> AsyncGenerator[AsyncSession, None]:
    session = async_session()
    try:
        yield session
        # 请求正常结束时提交会话
        await session.commit()
    except Exception as exc:
        # 发生异常时回滚
        await session.rollback()
        raise exc
    finally:
        # 无论是否异常,最终关闭会话,归还连接到连接池
        await session.close()

关键说明

  • 不要使用engine.dispose():该方法会销毁整个连接池,每次请求都需要重新建立数据库连接,直接导致性能暴跌。
  • 会话关闭的作用:await session.close()不会销毁连接,只是将连接归还到SQLAlchemy的连接池,供后续请求复用,避免频繁创建新连接。
  • 连接池参数调整:pool_size不要超过数据库允许的最大连接数(PostgreSQL默认是100),根据并发请求量合理设置。

内容的提问来源于stack exchange,提问作者Konstantin Komissarov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 03:00:54