SQLite 3 блокировка в PHP - PullRequest
       12

SQLite 3 блокировка в PHP

2 голосов
/ 23 мая 2011

Я хотел бы заблокировать базу данных SQLite3, сделать несколько запросов, а затем разблокировать ее.Как мне это сделать?

Ответы [ 3 ]

4 голосов
/ 24 мая 2011

Похоже, что единственный способ сделать это с PHP <5.3.3 - это использовать PDO.По-видимому, PDO по умолчанию устанавливает тайм-аут занятости на 60 секунд (в отличие от 0, установленного SQLite3), и вы также можете установить его явно с помощью <code>$pdo->setAttribute(PDO::ATTR_TIMEOUT, $timeout) (та же функциональность, что и в PHP 5.3.3 SQLite3::busyTimeout()).

3 голосов
/ 26 мая 2016

Существующие ответы полезны, но пропущены фрагменты истории.

Вы говорите, что хотите заблокировать базу данных, выполнить несколько запросов, а затем разблокировать ее .

Если вы делаете это, потому что вы не хотите, чтобы какой-либо другой процесс считывал базу данных, в то время как ваши изменения выполнены только частично, вы должны знать, что в SQLite есть функция, которая делает это ненужным: транзакции .

С транзакциями вы можете быть уверены, что никакой другой процесс не увидит ваши изменения, пока они не будут завершены, , но вам не нужно блокировать базу данных, пока вы их делаете . Фактически, пока вы вносите свои изменения, другие процессы могут по-прежнему считывать части базы данных, с которой вы работаете, и другие процессы, база данных будет продолжать выглядеть так же, как и до начала ваших изменений .

Как совершить транзакцию?

  1. Отправка BEGIN TRANSACTION в базу данных.
  2. Отправьте ваши запросы.
  3. Отправка COMMIT в базу данных (в качестве альтернативы база данных примет COMMIT TRANSACTION или даже END TRANSACTION в качестве синонимов).

Как происходит это волшебство?

Пока транзакция открыта, система базы данных не записывает ваши изменения обратно в оперативную базу данных, а записывает их в отдельную область памяти и / или диска. Пока это происходит, другие процессы могут свободно читать из базы данных, и они будут видеть базу данных без каких-либо ваших частичных изменений. После завершения транзакции система базы данных перепишет все ваши изменения в основную базу данных.

Технические детали этого различаются в разных базах данных, но все базы данных, поддерживающие транзакции, будут поддерживать эквивалентную функциональность, которая гарантирует, что другие процессы не увидят ваши незавершенные изменения.

Ваша проблема с другими процессами с ошибками

Даже если другие процессы могут продолжать читать базу данных, пока вы выполняете транзакцию, они все равно не смогут записывать в нее, и в конце вашей транзакции все равно будет очень небольшое время, в которое они будут иметь ждать либо читать, либо писать. Когда они попытаются это сделать, они заметят, что база данных заблокирована .

Это нормально. К сожалению, реализация SQLite3 в PHP (через PDO и класс SQLite3) не ждет получения блокировки, она просто останавливается с ошибкой. Такое поведение по умолчанию будет приемлемым, если вы когда-либо ожидаете, что только один клиент будет одновременно обращаться к базе данных, но неприемлемо в общей среде, такой как веб-сервер.

Итак, при открытии соединения SQLite3 вы всегда должны устанавливать время ожидания. В PHP 5.3.3 вы можете сделать это с помощью метода busyTimeout () SQLite3, но если у вас по какой-то причине нет доступа к нему, вы можете сделать это с помощью следующего SQL-запроса:

PRAGMA busy_timeout = 15000

Это в миллисекундах, так что это 15 секунд. Это должно работать независимо от вашей версии PHP и от того, используете ли вы класс PDO или SQLite3.

2 голосов
/ 23 мая 2011

Sqlite имеет транзакции, это очень похоже на то, что вы ищете. Смотри здесь

Вы, по сути, делаете что-то вроде этого:

BEGIN EXCLUSIVE TRANSACTION
UPDATE users SET foo=1 WHERE id=42
UPDATE fish  SET bass=2, cod=3 WHERE id=42
END TRANSACTION
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...