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

SQLite多线程读写遇‘database is locked’问题及选型咨询

问题分析与解答

一、「database is locked」错误的原因

结合你的代码和SQLite的锁机制,问题大概率出在这两点:

  • 写入端未及时释放锁:如果有其他进程/线程正在往test表写入tick数据,且写入操作没及时提交事务、或者事务执行时间过长,SQLite会持有全局独占写锁,后续查询请求因无法获取共享读锁,等待超时后就会触发锁错误。
  • 连接/游标管理不规范:你的代码没展示数据库连接创建逻辑,如果是全局共享一个连接/游标,且没设置合理的超时时间(sqlite3默认超时5秒),锁等待超过阈值就会报错。另外,如果在多线程环境下复用同一个连接(sqlite3默认不支持多线程共享连接),也会直接引发锁冲突。

你的查询逻辑本身没问题,但连接资源如果没及时释放,也可能间接加剧锁冲突。

二、SQLite是否适合这类同时读写的tick数据场景?

结论:不适合高频读写的tick数据场景,原因如下:

  • SQLite是文件型数据库,写操作会触发全局独占锁:只要有一个写入事务在执行,所有其他读写操作都会被阻塞。如果tick数据是高频写入(比如每秒几十上百条),会导致查询请求频繁被阻塞,甚至出现锁超时错误。
  • 并发性能有限:SQLite的设计定位是轻量、单进程/低并发场景,无法像MySQL、PostgreSQL这类客户端-服务器型数据库那样支持高并发读写分离、多连接并行处理。

如果你的tick数据写入频率极低(比如每秒几条),且查询压力不大,可以临时用SQLite,但需要做优化:

  • 延长连接超时时间:比如conn = sqlite3.connect('your_db.db', timeout=30),给锁等待留足时间
  • 写入端用短事务:每次写入后立即提交,不要长时间持有事务
  • 避免多线程共享同一个数据库连接,每个线程单独创建连接

优化后的查询代码示例

补全规范的连接管理逻辑,避免潜在的锁问题:

import sqlite3
import time

def get_ltp():
    # 每次查询创建独立连接(高并发场景可改用连接池)
    conn = sqlite3.connect('your_db.db', timeout=10)
    c = conn.cursor()
    try:
        query = """select * from test order by rowid desc LIMIT 1"""
        results = c.execute(query).fetchall()
        for i in results:
            print(i)
    finally:
        # 确保关闭连接释放资源
        conn.close()

for i in range(20):
    get_ltp()
    time.sleep(1) 

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 15:06:21