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

SQLite并发问题咨询:多进程下第二个进程无法获取数据库更新

解决SQLite多进程读写时查询无法获取更新的问题

首先,你的问题其实是SQLite默认事务隔离级别的特性导致的,我来给你拆解下原因和对应的解决办法:

问题根源

SQLite默认采用SERIALIZABLE隔离级别,当一个连接执行查询操作时,会自动开启一个隐式事务。只要这个事务没有被提交或回滚,该连接就会一直锁定在事务启动时的数据库快照状态——也就是说,其他连接提交的任何更新,这个未结束的事务都看不到。你的script2.py用同一个连接持续循环查询,事务从未终止,所以始终拿到的是第一次查询时的旧数据。

几种简单可行的解决方法

方法1:每次查询后提交/回滚事务

在script2.py的每次查询完成后,调用conn.commit()或者conn.rollback()(因为查询没有修改数据,回滚也能结束当前事务),这样下一次查询会开启新的事务,自然能获取到最新的数据库状态。

修改后的script2.py代码:

import sqlite3, time
conn = sqlite3.connect('test.db')
c = conn.cursor()
while True:
    c.execute('SELECT value FROM kv WHERE key = ?', (1,))
    item = c.fetchone()
    print(item)
    conn.commit()  # 提交事务,结束当前快照
    time.sleep(1)

方法2:修改连接的隔离级别为READ COMMITTED

SQLite支持READ COMMITTED隔离级别,在这个级别下,同一个事务内的后续查询可以看到其他连接已经提交的更新。你只需要在建立连接时指定这个隔离级别即可:

修改后的script2.py代码:

import sqlite3, time
# 建立连接时指定隔离级别为READ COMMITTED
conn = sqlite3.connect('test.db', isolation_level='READ COMMITTED')
c = conn.cursor()
while True:
    c.execute('SELECT value FROM kv WHERE key = ?', (1,))
    item = c.fetchone()
    print(item)
    time.sleep(1)

这个方法不需要频繁提交事务,更适合需要长期保持连接的场景。

方法3:每次查询重新建立连接(不推荐)

虽然可以每次查询都创建新连接,但频繁的连接创建与销毁会带来性能损耗,除非特殊场景,不建议使用这种方式:

import sqlite3, time
while True:
    with sqlite3.connect('test.db') as conn:
        c = conn.cursor()
        c.execute('SELECT value FROM kv WHERE key = ?', (1,))
        item = c.fetchone()
        print(item)
    time.sleep(1)

验证效果

任选上述一种方法修改后,重新启动script1.py和script2.py,你就能看到script2.py实时打印出script1.py更新的数值了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:29:48