【问题标题】:catch up SQLite error "database is locked"赶上 SQLite 错误“数据库已锁定”
【发布时间】:2020-01-07 19:06:38
【问题描述】:

我正在用 PHP 中的以下语句打开一个 SQLiteDB 运行良好。

$db2 = new SQLite3("/home/pi/ion.sqb", SQLITE3_OPEN_READONLY);
$resu2 = $db2->query("select * from test where name = 'Hans'");

但是我不时遇到以下错误消息 :: SQLite 被锁定并且 PHP 脚本会通过以下致命消息杀死自己:

PHP Warning:  SQLite3::query(): Unable to execute statement: database is locked in /home/pi/ion.sqb on line 559
PHP Fatal error:  Uncaught Error: Call to a member function fetchArray() on boolean in /home/pi/dbc.php:560
Stack trace:
#0 {main}
  thrown in /home/pi/dbc.php on line 560

我试图检查数据库是否被锁定并跳过选择...但是没有成功:

$db2 = new SQLite3("/home/pi/ion.sqb", SQLITE3_OPEN_READONLY);
$resu2 = $db2->query("select * from test where name = 'Hans'");
if (!$db2) {
    echo "DB DB-locked";
    }
else{ 
    $resu2 = $db2->query("select * from test where name = 'Hans'");
    while ($dsatz2 = $resu2->fetchArray(SQLITE3_ASSOC))
  ...

您可以在已记录的 SQLite DB 中遇到的问题是已知的 .. 当任何其他句柄处于写入模式时,也适用于选择。

我怎样才能发现我的脚本遇到致命错误并自行结束?

PHP Fatal error:  Uncaught Error: Call to a member function fetchArray() on boolean in /home/pi/dbc.php:560
Stack trace:
#0 {main}
  thrown in /home/pi/dbc.php on line 560

【问题讨论】:

  • 使用真正可以处理并发的数据库,例如:mariadb、postgres。您将无法以理智或高效的方式解决此问题。

标签: php sql sqlite


【解决方案1】:

这是一个应急问题。 sqlite 规范明确指出,在多进程(即 PHP,如果多个请求同时命中文件)或多线程环境中,如果两个 SELECT 查询同时命中同一个表,则“后”一个会得到这个错误。

不幸的是,在 PHP 中处理这个问题时,您没有太多选择。我什至不认为您可以在请求结束时结束的环境中启用共享缓存,因此即使这样也不可行。

老实说,在这种情况下,我建议进行微时间睡眠(例如,您平时 SELECT 持续时间的一半)并重试。

【讨论】:

  • 谢谢塞巴斯蒂安 - 我理解你正确吗,在我的“如果”期间它还没有被锁定,但是之后的毫秒,而我的“$resu2->fetchArray(SQLITE3_ASSOC))”..? ......所以睡觉会有帮助吗?
  • 睡眠重试可能会有所帮助,是的,但最终它只是延迟了不可避免的事情。事实是,相对于请求的数量,sqlite 并没有真正扩大规模。
  • Sebastien - 请问您是否有任何方法可以在我的 PHP 脚本中捕获错误消息?我的“ if (!$db2) ...” 不起作用。
猜你喜欢
  • 1970-01-01
  • 2022-01-22
  • 2010-10-28
  • 2012-02-09
  • 2018-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多