尝试从PHP脚本访问时数据库已锁定

Abh*_*nda 6 php sqlite concurrency

我正在编写一个与PHP后端通信的Android应用程序.后端db是SQLite 3.问题是,我间歇性地收到此错误PHP Warning: SQLite3::prepare(): Unable to prepare statement: 5, database is locked.我在每个PHP文件中打开与数据库的连接,并在脚本完成时关闭它.我认为问题是一个脚本在写入数据库时​​锁定了数据库文件,第二个脚本试图访问它,但失败了.避免这种情况的一种方法是共享所有PHP脚本之间的连接.我想知道是否还有其他方法可以避免这种情况?

编辑: 这是第一个文件:

<?php
$first = SQLite3::escapeString($_GET['first']);
$last = SQLite3::escapeString($_GET['last']);
$user = SQLite3::escapeString($_GET['user']);
$db = new SQLite3("database.db");
$insert = $db->prepare('INSERT INTO users VALUES(NULL,:user,:first,:last, 0 ,datetime())');
$insert->bindParam(':user', $user, SQLITE3_TEXT);
$insert->bindParam(':first', $first, SQLITE3_TEXT);
$insert->bindParam(':last', $last, SQLITE3_TEXT);
$insert->execute();
?>
Run Code Online (Sandbox Code Playgroud)

这是第二个文件:

<?php
$user = SQLite3::escapeString($_GET['user']);
$db = new SQLite3("database.db");
$checkquery = $db->prepare('SELECT allowed FROM users WHERE username=:user');
$checkquery->bindParam(':user', $user, SQLITE3_TEXT);
$results = $checkquery->execute();
$row = $results->fetchArray(SQLITE3_ASSOC);
print(json_encode($row['allowed']));
?>
Run Code Online (Sandbox Code Playgroud)

sla*_*pon 19

首先,当您完成资源后,您应该始终关闭它.从理论上讲,它将在垃圾收集时关闭,但你不能依赖PHP立即执行此操作.我已经看到一些数据库(以及其他类型的库)被锁定,因为我没有明确释放资源.

$db->close();
unset($db);
Run Code Online (Sandbox Code Playgroud)

其次,Sqlite3会给你一个忙碌的超时.我不确定默认值是什么,但如果您愿意等待几秒钟以便在执行查询时清除锁定,那么您可以这样说.超时以毫秒为单位.

$db->busyTimeout(5000);
Run Code Online (Sandbox Code Playgroud)

  • 即便如此,您可能会遇到问题.如果从脚本访问同一个DB而从另一个脚本(Ex:Ajax)仍然打开,那么您将遇到同样的问题 (3认同)

小智 5

我一直在"数据库锁定",直到我发现必须使用SQL特殊指令(即使用PRAGMA关键字)设置sqlite3的某些功能.例如,显然解决了我的"数据库锁定"问题的原因是将journal_mode设置为'wal'(它默认为'delete',如下所述:https://www.sqlite.org/wal.html(请参阅激活并配置WAL模式)).

所以我基本上要做的就是创建与数据库的连接并使用SQL语句设置journal_mode.例:

<?php
  $db = new SQLite3('/my/sqlite/file.sqlite3');
  $db->busyTimeout(5000);
  // WAL mode has better control over concurrency.
  // Source: https://www.sqlite.org/wal.html
  $db->exec('PRAGMA journal_mode = wal;');
?>
Run Code Online (Sandbox Code Playgroud)

希望有所帮助.