2012-03-26 95 views
5

我正在写一个与PHP后端进行通信的Android应用程序。后端数据库是SQLite 3.问题是,我间歇性地得到这个错误PHP Warning: SQLite3::prepare(): Unable to prepare statement: 5, database is locked。我打开每个PHP文件中的数据库连接并在脚本结束时关闭它。我认为问题在于一个脚本在写入数据库文件时锁定了数据库文件,第二个脚本试图访问它,失败了。避免这种情况的一种方法是共享所有的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(); 
?> 

这里是第二个文件:

<?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'])); 
?> 
+0

第一次共享代码 – 2012-03-26 03:33:55

+0

添加的代码和更多描述 – 2012-03-26 03:42:32

回答

13

首先,当你与资源做了你应该总是将其关闭。从理论上讲,垃圾收集时它会被关闭,但是你不能依赖PHP来做这件事。我已经看到一些数据库(以及其他类型的库)被锁定,因为我没有明确释放资源。

$db->close(); 
unset($db); 

其次,Sqlite3给你一个繁忙的超时。我不确定默认设置是什么,但是如果您希望在执行查询时等待几秒钟以清除锁定,则可以这样说。超时时间以毫秒为单位。

$db->busyTimeout(5000); 
+0

我其实忘了关闭连接。增加了那个和'busyTimeout'。现在工作正常。谢谢! – 2012-03-26 15:16:14

+3

即便如此,您可能会遇到问题。如果从另一个脚本(例如:Ajax)仍然打开时从脚本访问相同的数据库,则会出现同样的问题 – Alex 2012-05-07 07:58:51

+0

默认值为60秒== 60000毫秒。 5000如何做一件有用的事情? – TechJS 2016-07-13 13:12:43

1

,直到我发现了sqlite3的一些功能必须通过使用SQL特殊指令(即使用关键字PRAGMA)来设置我得到的“数据库锁定”的所有时间。例如,“数据库锁定”显然解决了我的问题是将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;'); 
?> 

希望有帮助。

相关问题