2012-03-26 93 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;'); 
?> 

希望有幫助。

相關問題