作者:ex7776647 | 来源:互联网 | 2022-11-30 09:27
我有时会偶然遇到:
OperationalError:数据库已锁定
在更新SQLite数据库的过程中,但是我发现很难重现该错误:
没有其他进程同时插入/删除行
只有一个进程可以SELECT
在此处和那里执行一些只读查询(等),但是没有提交
我已经读过OperationalError:数据库已锁定
问题:是否有办法在发生此错误时记录哪个其他进程ID负责锁定?
更一般而言,如何调试OperationalError: database is locked
?
1> Basj..:
解决方案:始终关闭cursor
for(甚至只读)查询!
首先,这是重现问题的一种方法:
第一次运行此代码,一次:
import sqlite3
cOnn= sqlite3.connect('anothertest.db')
conn.execute("CREATE TABLE IF NOT EXISTS mytable (id int, description text)")
for i in range(100):
conn.execute("INSERT INTO mytable VALUES(%i, 'hello')" % i)
conn.commit()
初始化测试。
然后开始一个只读查询:
import sqlite3, time
cOnn= sqlite3.connect('anothertest.db')
c = conn.cursor()
c.execute('SELECT * FROM mytable')
item = c.fetchone()
print(item)
print('Sleeping 60 seconds but the cursor is not closed...')
time.sleep(60)
并在执行下一步时保持此脚本运行:
然后尝试删除一些内容并提交:
import sqlite3
cOnn= sqlite3.connect('anothertest.db')
conn.execute("DELETE FROM mytable WHERE id > 90")
conn.commit()
确实会触发此错误:
sqlite3.OperationalError:数据库已锁定
为什么?由于无法删除读取查询当前正在访问的数据:如果游标仍处于打开状态,则意味着仍可以使用fetchone
或来获取数据fetchall
。
解决错误的方法如下:在步骤2中,只需添加:
item = c.fetchone()
print(item)
c.close()
time.sleep(60)
然后,在此脚本仍在运行的同时,启动脚本#3,您将看到没有更多错误。