2015-01-12 6 views
2

У меня есть этот небольшой тестовый скрипт:Sqlite3, SQLSTATE [HY000]: Общая ошибка: 5 база данных заблокирована

session_start(); 
session_write_close(); 
error_reporting(-1); 
register_shutdown_function(function() { 
    //echo 'shutdown'; 
}); 

$MAX = 120; 
set_time_limit($MAX); 
echo date('Y-m-d H:i:s').'<br>'; 
$m = microtime(true); 
$file_db = new PDO('sqlite:'.dirname(__FILE__).'/test.sqlite3'); 
$file_db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
$file_db->exec("CREATE TABLE IF NOT EXISTS messages (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, message TEXT, time INTEGER)"); 

$d = date('U'); 
do 
{ 
    $file_db->exec ('INSERT INTO messages VALUES (null, "titleee'.rand(1,9).'", "MESSAGEEEE'.rand(1,99).'", "'.rand(1,999).'")'); 
    if (date('U') - $d > $MAX/2) 
    { 
     break; 
    } 
} while (true); 
$file_db = null; 
echo 'ok: '.(microtime(true)-$m); 

, если это выполняется в браузере в нескольких, например, рано или поздно он упадет «SQLSTATE [HY000 ]: Общая ошибка: исключение 5 базы данных заблокировано. Как уклониться от этого?

+1

Добавить: sleep (2) после '$ file_db-> exec' Слишком много процессов пытаются слишком быстро вставить в базу данных, которая блокирует таблицу. –

+0

Хм, не может ли он быть установленным, чтобы он «зависал», пока его не заблокировали? –

+1

Никогда не использовал это, но вы можете попробовать: '$ file_db-> query (" SET LOCK MODE TO WAIT 120 ")' сразу же после создания экземпляра '$ file_db'. Это должно заставить скрипт ждать до двух минут, чтобы таблица разблокировалась ... –

ответ

1

Добавить: sleep(2) после $file_db->exec Слишком много процессов пытаются слишком быстро вставить в базу данных, которая блокирует таблицу. Вы можете попробовать: $file_db->query("SET LOCK MODE TO WAIT 120") сразу после создания экземпляра $file_db. Это должно заставить скрипт ждать до двух минут, чтобы таблица разблокировала ...

+0

Я добавил «$ file_db-> setAttribute (PDO :: ATTR_TIMEOUT, 0);" и я поймаю исключение. Если это исключение имеет место, я просто снова запускаю этот запрос +, я делаю «спящий» - это работает теоретически, не так ли? –

+1

Да, в теории, которая будет работать нормально, хотя вы можете начать с спящего на вид смещения попыток немного ... –

+0

нет, его нет. Кажется, что этот замок «взаимный». –

2

У меня была эта ошибка, потому что у меня была несохраненная запись на SQLiteBrowser, тогда SQLite не писал бы на ней. Мой скрипт возобновил работу, как только я сохранил запись. Таким образом, каждый раз, когда возникает эта ошибка, проверьте, включен ли SQLiteBrowser (или любой другой редактор), и имеет какие-либо несохраненные изменения.

1

я отследил вопрос блокировки к машине сетевой проблемы виртуального обмена файлов: https://www.sqlite.org/lockingv3.html#how_to_corrupt

One should note that POSIX advisory locking is known to be buggy or even unimplemented on many NFS implementations (including recent versions of Mac OS X) and that there are reports of locking problems for network filesystems under Windows. Your best defense is to not use SQLite for files on a network filesystem.

Я был в состоянии решить эту проблему путем перемещения файла базы данных SQLite в гостевой ОС (Linux) каталога который не монтируется/не используется совместно с ОС хоста (Windows).

В моем случае я переместил файл базы данных SQLite в /tmp на гостевую ОС Linux.

Смежные вопросы