我可以等待 cli 上的 sqlite 锁被释放吗?

ssi*_*ono 5 sqlite locking command-line-interface thread-safety

我有一个 sqlite3 数据库文件,多个进程通过 shell 脚本中的 sqlite3 命令实用程序同时访问该文件。

这有时会导致database is locked编写时出现某种错误。

问题是我没有任何性能问题,但我只是希望每个查询都阻塞,直到数据库解锁,然后完成其工作。现在它只是失败了,所以唯一的方法就是捕获失败并继续重试。

有什么办法可以实现这一点吗?

我检查了有关sqlite 线程安全的文档,它基本上说序列化模式是最“线程友好”的。检查编译选项时

echo 'pragma compile_options' | sqlite3 db.db | grep -i threadsafe
Run Code Online (Sandbox Code Playgroud)

我知道THREADSAFE=1哪个确实是序列化的(默认)。

这是一个演示该问题的示例脚本:

#! /bin/bash

rm -f db.db

echo 'CREATE TABLE animals (
  id integer primary key autoincrement,
  name varchar
)' | sqlite3 db.db

echo "insert into animals(name) values('rabbit')" | sqlite3 db.db &
echo "insert into animals(name) values('rabbit')" | sqlite3 db.db &
echo "insert into animals(name) values('rabbit')" | sqlite3 db.db &
echo "insert into animals(name) values('rabbit')" | sqlite3 db.db &
echo "insert into animals(name) values('rabbit')" | sqlite3 db.db &

Run Code Online (Sandbox Code Playgroud)

输出是这样的

Error: near line 1: database is locked
Error: near line 1: database is locked
Error: near line 1: database is locked
Run Code Online (Sandbox Code Playgroud)

五只动物中只有两只被插入。我只希望每个查询都能成功,即使由于请求排队而需要更多时间。


sqlite3 版本 3.22.0

Sha*_*awn 5

sqlite3 shell 的命令可用于指定在尝试打开锁定的数据库时在给出错误之前.timeout等待的毫秒数。因此,请尝试更改您的脚本来使用它;像这样的东西:

#!/bin/bash

# A 1 second busy timeout
timeout=1000

rm -f db.db

sqlite3 db.db <<EOF
CREATE TABLE animals (
  id integer primary key autoincrement,
  name text
);
EOF

sqlite3 db.db <<EOF &
.timeout $timeout
insert into animals(name) values('rabbit 1');
EOF

sqlite3 db.db <<EOF &
.timeout $timeout
insert into animals(name) values('rabbit 2');
EOF

sqlite3 db.db <<EOF &
.timeout $timeout
insert into animals(name) values('rabbit 3');
EOF

sqlite3 db.db <<EOF &
.timeout $timeout
insert into animals(name) values('rabbit 4');
EOF
Run Code Online (Sandbox Code Playgroud)

请注意使用heredocs,而不是使用echo. 当向脚本中的进程标准输入发送大量文字文本时,它们会派上用场。

这也与线程无关;这些都是单独的进程,而不是线程。

  • 是的,它有效,这正是我一直在寻找的。非常感谢@肖恩!还可以使用“sqlite3 -cmd '.timeout 1000' db.db”将会话配置与查询本身分开。 (4认同)