我可以等待在 cli 上释放 sqlite 锁吗?
Can i wait for sqlite lock to be released on the cli?
我有一个 sqlite3 数据库文件,多个进程通过来自 shell 个脚本的 sqlite3 命令实用程序同时访问它。
这有时会在写入时导致一些 database is locked
类错误。
问题是我没有任何性能问题,但我只想让每个查询都阻塞,直到数据库解锁,然后再执行它的工作。现在它只是失败了,所以唯一的办法就是抓住失败并继续重试。
有什么办法可以实现吗?
我查看了关于thread safety with sqlite的文档,基本上说序列化模式是最多的"thread friendly"。检查编译选项时
echo 'pragma compile_options' | sqlite3 db.db | grep -i threadsafe
我得到 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 &
输出类似于
Error: near line 1: database is locked
Error: near line 1: database is locked
Error: near line 1: database is locked
5 只动物中只有 2 只被插入。我只希望每个查询都能成功,即使由于请求排队需要更多时间。
sqlite3 版本 3.22.0
sqlite3 shell的.timeout
命令可用于指定wait while trying to open a locked database出现错误前的毫秒数。因此,请尝试更改您的脚本以使用它;像这样:
#!/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
注意使用 heredocs,而不是使用 echo
。在将大量文字文本发送到脚本中的进程标准输入时,它们会派上用场。
这也与线程无关;这些都是独立的进程,而不是线程。
我有一个 sqlite3 数据库文件,多个进程通过来自 shell 个脚本的 sqlite3 命令实用程序同时访问它。
这有时会在写入时导致一些 database is locked
类错误。
问题是我没有任何性能问题,但我只想让每个查询都阻塞,直到数据库解锁,然后再执行它的工作。现在它只是失败了,所以唯一的办法就是抓住失败并继续重试。
有什么办法可以实现吗?
我查看了关于thread safety with sqlite的文档,基本上说序列化模式是最多的"thread friendly"。检查编译选项时
echo 'pragma compile_options' | sqlite3 db.db | grep -i threadsafe
我得到 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 &
输出类似于
Error: near line 1: database is locked
Error: near line 1: database is locked
Error: near line 1: database is locked
5 只动物中只有 2 只被插入。我只希望每个查询都能成功,即使由于请求排队需要更多时间。
sqlite3 版本 3.22.0
sqlite3 shell的.timeout
命令可用于指定wait while trying to open a locked database出现错误前的毫秒数。因此,请尝试更改您的脚本以使用它;像这样:
#!/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
注意使用 heredocs,而不是使用 echo
。在将大量文字文本发送到脚本中的进程标准输入时,它们会派上用场。
这也与线程无关;这些都是独立的进程,而不是线程。