2009-02-19 61 views
5

Tôi đã chuẩn bị 2 tệp, "1.php" và "2.php".Giao dịch SQLite không hoạt động như mong đợi

"1.php" là như thế này.

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

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

print "bbb"; 
?> 

và "2.php" là như thế này.

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

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

và tôi thực hiện "1.php". Nó bắt đầu một giao dịch và chờ 55 giây.

Vì vậy, khi tôi ngay lập tức thực thi "2.php", mong đợi của tôi là thế này:

  1. "1.php" là nhận được giao dịch và
  2. "1" nắm giữ một cơ sở dữ liệu khóa
  3. "2 "không thể bắt đầu một giao dịch
  4. '2' không thể có được khóa cơ sở dữ liệu để
  5. '2' phải đợi 55 giây

NHƯNG, nhưng thử nghiệm đã đi theo một cách khác. Khi tôi thực thi "2", sau đó

  1. "2" ngay lập tức quay trở lại đó là kết quả
  2. "2" không đợi

vì vậy tôi phải suy nghĩ rằng "1" không thể có được giao dịch, hoặc không thể lấy khóa cơ sở dữ liệu.

Có ai giúp được không?

Trả lời

9

Theo tôi được biết, các giao dịch SQLite không khóa cơ sở dữ liệu trừ khi

  • a. bạn tạo chúng EXCLUSIVE (chúng là DEFERRED theo mặc định) hoặc
  • b. bạn thực sự truy cập vào cơ sở dữ liệu

Vì vậy, hoặc là bạn một cách rõ ràng gọi

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

hoặc bạn thực hiện một thao tác ghi (INSERT/UPDATE) để DB trước khi bạn bắt đầu để sleep().

Để trích dẫn (tôi nhấn mạnh) documentation:

giao dịch có thể được hoãn lại, ngay lập tức, hoặc độc quyền. Hành vi giao dịch mặc định được hoãn lại. Hoãn nghĩa là không có khóa nào là được mua trên cơ sở dữ liệu cho đến khi cơ sở dữ liệu được truy cập lần đầu tiên. Do đó, với giao dịch bị trì hoãn, chính tuyên bố BEGIN không có tác dụng gì. Khóa không được mua cho đến khi đọc lần đầu tiên hoặc ghi hoạt động.Lần đọc đầu tiên hoạt động đối với cơ sở dữ liệu tạo ra khóa SHARED và thao tác viết đầu tiên hoạt động sẽ tạo khóa RESERVED.

Các vấn đề liên quan