使用sqlite3命令行时出现“数据库被锁定”错误

6
我使用命令行sqlite3来进行操作,从bash启动。
我生成多个进程,所有进程都试图向同一sqlite数据库文件中插入数据。
经常出现“数据库已锁定”的情况。
根据我对文档(http://www.sqlite.org/cvstrac/wiki?p=DatabaseIsLocked)的理解,这种情况不应该发生:“SQLITE_LOCKED表示争用源来自相同的数据库连接,并收到SQLITE_LOCKED错误”。
由于sqlite3命令行是单线程的,因此我期望在此情况下出现SQLITE_BUSY,但不会出现SQLITE_LOCKED。
代码:
doit() {
   sqlite3 /tmp/db "insert into foo(a,b,c) values(1,2,3);
}

doit &; doit &; doit &

我尝试添加PRAGMA busy_timeout=2000;和PRAGMA locking_mode=EXCLUSIVE;,但是没有帮助。

sqlite3 -version
3.8.9 2015-04-08 12:16:33 8a8ffc862e96f57aa698f93de10dee28e69f6e09
2个回答

9
SQLITE_BUSY的错误信息是“database is locked”,而SQLITE_LOCKED则是“database table is locked”。
以下代码对我有效(没有busy_timeout会导致错误):
doit() {
   sqlite3 /tmp/db "pragma busy_timeout=20000; insert into foo(a,b,c) values(1,2,3);"
}

嗯,你可能是对的。可以称之为消息混淆。现在我可以通过以下任一方式实现相同的效果:sqlite3 -init <(echo .timeout 20000) 或 PRAGMA busy_timeout=20000; 你知道.timeout指令是否等同于该pragma吗? - Dmitry z
".timeout"完全相同。 - CL.

5

在DBA StackExchange上有一个关于这个问题的好回答。它的要点是在初始化时运行.timeout 1000,告诉命令行工具等待1秒钟以获取锁定。我不确定这个超时是否与您提到的pragma busy_tmeout相同或不同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接