Транзакция SQLite не работает должным образом - PullRequest
5 голосов
/ 19 февраля 2009

Я подготовил 2 файла: «1.php» и «2.php».

"1.php" похож на это.

<?php
$dbh = new PDO('sqlite:test1');
$dbh->beginTransaction();

print "aaa<br>";
sleep(55);
$dbh->commit();

print "bbb";
?>

и "2.php" похожи на это.

<?php
$dbh = new PDO('sqlite:test1');
$dbh->beginTransaction();

print "ccc<br>";
$dbh->commit();
print "ddd";
?>

и я прошу прощения "1.php". Он начинает транзакцию и ждет 55 секунд.

Поэтому, когда я сразу же извиняюсь за «2.php», я ожидаю, что это:

  1. «1.php» получает транзакцию и
  2. «1» удерживает блокировку базы данных
  3. «2» не может начать транзакцию
  4. "2" не может получить блокировку базы данных, поэтому
  5. "2" должны ждать 55 секунд

НО, но тест пошел другим путем. Когда я извиняюсь "2", то

  1. "2" немедленно вернул свой результат
  2. «2» не ждал

поэтому я должен думать, что "1" не может получить транзакцию или не может получить блокировку базы данных.

Может кто-нибудь помочь?

1 Ответ

9 голосов
/ 19 февраля 2009

Насколько я понимаю, транзакции SQLite не блокируют базу данных, если

  • а. вы делаете их EXCLUSIVE (они DEFERRED по умолчанию) или
  • б. вы фактически получаете доступ к базе данных

Так что либо вы явно звоните

$dbh->exec("BEGIN EXCLUSIVE TRANSACTION");

или вы выполняете операцию записи (INSERT / UPDATE) в БД перед началом sleep().

Для цитирования документации (выделено мной):

Транзакции могут быть отложены, немедленный или эксклюзивный. по умолчанию поведение транзакции откладывается. Отложено означает, что нет блокировки приобретенные в базе данных, пока база данных сначала доступна. Таким образом, с отложенная транзакция, BEGIN Само заявление ничего не делает. Замки не приобретены до первого чтения или операция записи. Первое чтение операция с базой данных создает ОБЩАЯ блокировка и первая запись операция создает зарезервированную блокировку.

...