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

当isolation_level为AUTOCOMMIT时,未关闭AsyncSession会引发连接泄漏吗?

AsyncSession未关闭的问题解答

1. 不关闭AsyncSession会发生什么?

  • SQLAlchemy的AsyncSession会持有连接池中的数据库连接,不主动关闭的话,连接不会立刻归还到连接池。
  • Python垃圾回收器(GC)最终会回收AsyncSession对象并触发连接清理,但这个回收时机完全不可控。
  • 你遇到的报错就是因为GC在asyncio事件循环已经关闭后才尝试清理连接:asyncpg的连接终止操作需要在事件循环运行时执行,循环关闭后就会抛出RuntimeError: Event loop is closed。同时SQLAlchemy会抛出SAWarning,提醒你应该显式管理连接生命周期。

2. 是否安全?

  • 不安全。虽然GC最终会处理连接,但过程中会产生警告和错误,污染日志输出;在高并发场景下,未及时归还的连接会占用连接池名额,导致后续请求无法获取连接,甚至触发连接池不必要的扩容,额外消耗服务器资源。

3. 是否会引发连接泄漏?

  • 属于临时泄漏:严格来说不算永久泄漏(GC最终会回收),但在GC触发前,被占用的连接无法被复用。高负载场景下,大量未关闭的Session会直接把连接池占满,表现得和永久连接泄漏一样,导致服务无法处理新请求。

正确的处理方式

必须显式管理AsyncSession的生命周期,推荐两种做法:

方式一:显式调用close()

import asyncio
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy import text

engine = create_async_engine("postgresql+asyncpg://postgres:postgres@localhost:5432/postgres", isolation_level="AUTOCOMMIT")

async def main():
    session = AsyncSession(engine)
    try:
        print(await session.execute(text("SELECT 1")))
    finally:
        await session.close()  # 显式关闭会话,将连接归还到池

if __name__ == '__main__':
    asyncio.run(main())

方式二:使用async with上下文管理器(更简洁安全)

import asyncio
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy import text

engine = create_async_engine("postgresql+asyncpg://postgres:postgres@localhost:5432/postgres", isolation_level="AUTOCOMMIT")

async def main():
    async with AsyncSession(engine) as session:
        print(await session.execute(text("SELECT 1")))
    # 上下文管理器会自动关闭会话,无需手动调用close()

if __name__ == '__main__':
    asyncio.run(main())

内容的提问来源于stack exchange,提问作者Альберт Александров

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 07:04:55