2009-02-19 12 views
5

Ich bereitete 2 Dateien vor, "1.php" und "2.php".SQLite-Transaktion funktioniert nicht wie erwartet

"1.php" ist wie folgt.

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

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

print "bbb"; 
?> 

und "2.php" ist wie folgt.

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

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

und ich execute "1.php". Es startet eine Transaktion und wartet 55 Sekunden.

Also, wenn ich sofort excute "2.php", ist meine Erwartung dies:

  1. "1.php" wird immer Transaktion und
  2. "1" hält eine Datenbank sperren
  3. „2 "kann nicht eine Transaktion beginnen
  4. "2" kann nicht Datenbank-Sperre erhalten so
  5. "2" haben bis 55 Sekunden warten

ABER, aber der Test ging anders. Als ich "2" excute, dann

  1. "2" sofort zurück es Ergebnis ist
  2. "2" nicht warten

so muß ich denke, dass "1" nicht Transaktion erhalten könnte, oder konnte keine Datenbanksperre erhalten.

Kann jemand helfen?

Antwort

9

Wie ich es verstehe, SQLite Transaktionen sperren die Datenbank nicht, es sei denn

  • ein. Sie machen sie EXCLUSIVE (sie sind standardmäßig DEFERRED) oder
  • b. Sie Zugriff auf die Datenbank tatsächlich

Also entweder explizit Sie

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

oder Sie einen Schreibvorgang machen rufen (INSERT/UPDATE) an die DB, bevor Sie zu sleep() starten.

Um die documentation (Hervorhebung von mir) zu zitieren:

Transaktionen aufgeschoben werden kann, sofort oder exklusiv. Das Standardtransaktionsverhalten ist verzögert. Zurückgestellt bedeutet, dass in der Datenbank keine Sperren erfasst werden, bis zuerst auf die Datenbank zugegriffen wird. Also mit eine zurückgestellte Transaktion, die BEGIN Anweisung selbst tut nichts. Sperren werden erst beim ersten Lesen oder Schreibvorgang erfasst.Die erste Leseoperation für eine Datenbank erstellt eine SHARED-Sperre, und die erste Schreiboperation erstellt eine RESERVED-Sperre.