如果数据库被锁定,重试 SQLite 查询的最简单方法?

2024-04-14

我不太确定在哪里问,我希望就在这里。

我寻找的是在数据库繁忙时重试 SQLite 查询的最简单的解决方案。 我在服务器上使用 quassel 作为 IRC 客户端,并且希望将旧日志移至单独的数据库以保持其使用的较小规模。 我为此编写的脚本是:

CREATE TEMP TABLE delfrom (id integer,val integer);
ATTACH '/home/irc/oldlog.db' as log;
BEGIN IMMEDIATE;
REPLACE INTO delfrom (id,val) select 1337,messageid from backlog where time < strftime('%s', 'now','-14 days') ORDER BY messageid DESC LIMIT 1;
INSERT INTO log.log (messageid,time,bufferid,type,flags,senderid,message) SELECT messageid,time,bufferid,type,flags,senderid,message FROM backlog WHERE messageid < (SELECT val FROM delfrom where id=1337);
DELETE FROM backlog WHERE messageid < (SELECT val FROM delfrom where id=1337);
PRAGMA incremental_vacuum;
COMMIT;

我使用 sqlite3 quassel-storage.sqlite

问题是,由于 quassel 在执行时正在运行,有时BEGIN IMMEDIATE;失败,因为数据库被锁定。

有人可以建议我一种简单的方法来更改该设置,以便每隔几秒钟重试一次查询,直到它起作用吗? 我读到 python SQLite 包装器内置了这个?有没有一种特殊的方法我必须激活它,更重要的是,我可以使用 python 附加第二个数据库吗? 有一个超时参数sqlite3.connect但我不太确定这是如何运作的。 Python 是否会锁定整个数据库以便在每次连接时进行写入?

我决不固定使用Python。我更喜欢的解决方案是,当发生此错误时,sqlite3 返回 0,然后将其包装在 shell 中的循环中,但这似乎不起作用。


如果您的版本大于 3.7,请对 Sqlite 使用 WAL 模式https://www.sqlite.org/wal.html https://www.sqlite.org/wal.html

connect = sqlite3.connect(DB, **kwargs)
connect.execute("PRAGMA journal_mode=WAL")

根据文档,“WAL 提供了更多的并发性,因为读取器不会阻止写入器,写入器也不会阻止读取器。读取和写入可以同时进行。”

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如果数据库被锁定,重试 SQLite 查询的最简单方法? 的相关文章

随机推荐