讲师中心 微信公众号

工具推荐

视频效率加速
立刻MV
立刻MV

低成本歌曲 MV、视频生成

updream

一键生成高质量推广成片

AniShort
AniShort

AI短剧协同制作平台

剧云
剧云

中文短剧剧本制作平台

SQLite3 异步查询阻塞问题的根源与解决方案

轻枫小哥_8471

轻枫小哥_8471

发布时间:2026-03-23 22:55:01

|

311人浏览过

|

来源于php中文网

原创

SQLite3 异步查询阻塞问题的根源与解决方案

Flask 应用中使用 SQLAlchemy Async + SQLite 时,异步数据库查询仍被长时间 API 调用阻塞,根本原因在于默认连接池不兼容异步 I/O 模型;正确配置 AsyncAdaptedQueuePool 并禁用线程限制可彻底解决该问题。

flask 应用中使用 sqlalchemy async + sqlite 时,异步数据库查询仍被长时间 api 调用阻塞,根本原因在于默认连接池不兼容异步 i/o 模型;正确配置 `asyncadaptedqueuepool` 并禁用线程限制可彻底解决该问题。

在基于 Flask 的全异步 API 服务中,即使已采用 sqlalchemy.ext.asyncio 和 aiosqlite,SQLite 的异步查询仍可能表现出严重延迟(如从 100ms 升至 10s+),尤其当存在其他耗时请求(如外部 HTTP 调用、CPU 密集型处理)时。这不是代码逻辑错误,而是 SQLite 异步驱动与 SQLAlchemy 连接池协同机制的关键误区:create_async_engine 默认不启用真正的异步连接复用能力,且 SQLite 的 aiosqlite 后端必须配合专用异步连接池类,否则所有 DB 操作将隐式串行化或受全局锁制约。

✅ 正确配置异步 SQLite 引擎

核心修复在于显式指定 poolclass=AsyncAdaptedQueuePool —— 这是 SQLAlchemy 官方为 aiosqlite 专门设计的异步感知连接池,它确保连接获取、释放和复用全程非阻塞,并与 asyncio 事件循环无缝协作。

修改 database/db.py 如下:

from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker, AsyncSession
from sqlalchemy import NullPool, text
from sqlalchemy.pool import AsyncAdaptedQueuePool  # ✅ 关键导入

# 替换原 engine 创建方式
engine = create_async_engine(
    "sqlite+aiosqlite:///main.sqlite3",
    echo=False,                    # 生产环境建议关闭
    future=True,
    poolclass=AsyncAdaptedQueuePool,  # ✅ 强制启用异步连接池
    connect_args={
        "check_same_thread": False,  # ✅ 必须禁用,否则 aiosqlite 报错
        "timeout": 30.0,
    },
    # 可选:限制连接数防资源耗尽(SQLite 通常 1–5 足够)
    pool_size=5,
    max_overflow=10,
)

# 推荐:统一 session 工厂定义(避免每次调用重建)
AsyncSessionLocal = async_sessionmaker(
    bind=engine,
    class_=AsyncSession,
    expire_on_commit=False,
    autoflush=False,
)

# 使用示例(在 actions.py 中)
async def get_customer(api_key):
    async with AsyncSessionLocal() as session:  # ✅ 直接使用工厂实例
        async with session.begin():
            stmt = select(ApiKey).where(ApiKey.api_key == api_key)
            result = await session.execute(stmt)
            key = result.scalars().first()
            return {"id": key.id, "api_key": key.api_key, "owner_name": key.owner_name} if key else None

⚠️ 关键注意事项:

  • check_same_thread=False 是 aiosqlite 的强制要求,否则会抛出 ProgrammingError: SQLite objects created in a thread can only be used in that same thread;
  • 绝对不要混用同步与异步引擎/会话:删除 Flask-SQLAlchemy 的 SQLAlchemy() 实例(即 db = SQLAlchemy(...)),它本质是同步 ORM 封装,与 AsyncSession 不兼容,会导致未定义行为;
  • NullPool 或 QueuePool 在异步场景下完全无效甚至有害,它们属于同步池类,无法参与 asyncio 调度。

? 为什么原代码会失败?

  • 原 create_async_engine(...) 未指定 poolclass,SQLAlchemy 会尝试使用默认同步池(如 QueuePool),触发 Pool class cannot be used with asyncio engine 类似警告(某些版本静默降级);
  • Flask-SQLAlchemy 的 db 实例初始化了同步上下文管理器,与 async_sessionmaker 冲突,造成会话生命周期混乱;
  • SQLite 文件锁机制在高并发下易成为瓶颈,而错误的池配置会让多个协程争抢同一连接,实际退化为串行执行。

✅ 验证修复效果

部署后可通过并发压测验证解耦性:

# 终端 1:发起长耗时请求(模拟 heavy_call)
curl "http://localhost:5000/api/call?api-key=test"

# 终端 2:同时发起轻量 DB 查询(应 <200ms 返回)
curl "http://localhost:5000/api/customers?api-key=test"

若第二请求不再等待第一请求结束,则说明异步 I/O 已真正并行化。

? 补充建议

  • 生产环境慎用 SQLite 异步:尽管 aiosqlite 可工作,但 SQLite 本身是文件数据库,写操作全局互斥。高频写入场景建议迁移到 PostgreSQL + asyncpg;
  • 添加连接健康检查(可选):
    @app.before_serving
    async def init_db():
        async with engine.begin() as conn:
            await conn.run_sync(lambda c: c.execute(text("PRAGMA journal_mode = WAL;")))
  • 日志增强调试:启用 echo=True 和 logging.basicConfig(level=logging.INFO) 观察 SQL 执行时间戳,精准定位阻塞点。

通过以上配置,你的 Flask 异步应用将真正实现「DB 查询不被业务逻辑阻塞」,充分发挥 asyncio 的并发优势。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

相关专题

更多
python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

1911

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

5344

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

1849

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

32357

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

3807

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

3827

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

1263

2023.08.11

python合并两个列表
python合并两个列表

Python是一种强大的编程语言,具有许多方便的功能和工具。在Python中,有多种方法可以合并两个列表。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

616

2023.08.10

Go-Zero API开发使用教程
Go-Zero API开发使用教程

本专题聚焦Go-Zero的API开发,拆解.api描述文件的语法结构、路由与分组定义、参数绑定与校验规则,说明统一响应体、JWT鉴权、跨域与接口文档生成的落地方式,并给出网关聚合与接口测试的实践建议。

0

2026.11.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn