2010-07-26 34 views
6

Tôi nghĩ rằng câu hỏi chính nó là khá tự giải thích. Mã được đưa ra bên dưới -Tại sao giao dịch PDO sau đây cam kết?

<?php 
    $PDO = NULL; 
    $pdo_dsn = 'mysql:host=localhost;dbname=pdo_test'; 
    $pdo_persistence = array(PDO::ATTR_PERSISTENT => true); 
    $db_user = 'root'; 
    $db_pass = ''; 
    $db_query = "INSERT INTO person(name, address) 
        VALUES ('Mamsi Mamsi', 'Katabon')"; 

    try 
    { 
      $PDO = new PDO($pdo_dsn, $db_user, $db_pass, 
           $pdo_persistence); 
    } 
    catch(PDOException $e) 
    { 
      echo "Error occured: ". $e->getMessage(); 
      die(); 
    } 

    $PDO->setAttribute(PDO::ATTR_ERRMODE, 
          PDO::ERRMODE_EXCEPTION); 
    $PDO->setAttribute(PDO::ATTR_AUTOCOMMIT, false); 

    try 
    { 
      $PDO->beginTransaction(); 
      $PDO->exec($db_query); 

      throw new PDOException('Generated Exception'); 

      $PDO->commit(); 
    } 
    catch(PDOException $e) 
    { 
      echo "An error occured while doing a database transaction. The 
      error message is : ".$e->getMessage(); 

      $PDO->rollBack(); 
      die(); 
    } 
?> 

Ngay cả khi tôi đang quay lại giao dịch bên trong khối catch, dữ liệu vẫn đang được chèn vào cơ sở dữ liệu. Tại sao?

EDIT

tôi thêm một vài dòng sau từ documentation để biết thêm làm rõ -

Thật không may, không phải tất cả cơ sở dữ liệu hỗ trợ giao dịch, vì vậy PDO cần để chạy trong những gì được gọi là Chế độ "tự động cam kết" khi bạn lần đầu tiên mở kết nối . Chế độ tự động cam kết có nghĩa là mọi truy vấn mà bạn chạy có giao dịch tiềm ẩn của riêng nó, nếu cơ sở dữ liệu hỗ trợ hoặc không có giao dịch nếu cơ sở dữ liệu không hỗ trợ giao dịch. Nếu bạn cần một giao dịch, bạn phải sử dụng phương pháp PDO :: beginTransaction() để bắt đầu một giao dịch. Nếu trình điều khiển cơ bản không hỗ trợ các giao dịch, một PDOException sẽ được ném (bất kể lỗi của bạn xử lý các cài đặt : đây luôn là điều kiện lỗi nghiêm trọng). Khi bạn đang ở trong giao dịch , bạn có thể sử dụng PDO :: cam kết() hoặc PDO :: rollBack() để hoàn thành tùy chọn thành công của mã bạn chạy trong giao dịch .

Ngoài ra, các dòng sau từ this trang -

bool PDO::beginTransaction (void ) 

Tắt chế độ autocommit. Trong khi chế độ tự động được tắt, thay đổi được thực hiện cho cơ sở dữ liệu thông qua đối tượng PDO đối tượng không phải là cam kết cho đến khi bạn kết thúc giao dịch bằng cách gọi PDO :: commit(). Gọi PDO :: rollBack() sẽ quay trở lại tất cả các thay đổi đối với cơ sở dữ liệu và trả kết nối về chế độ tự động.

Một số cơ sở dữ liệu, bao gồm MySQL, tự động phát hành câu hỏi ngụ ý COMMIT ngầm định khi có tuyên bố ngôn ngữ định nghĩa cơ sở dữ liệu (DDL) chẳng hạn như DROP TABLE hoặc CREATE TABLE. COMMIT tiềm ẩn sẽ ngăn bạn quay lại bất kỳ thay đổi nào khác trong ranh giới giao dịch.

+0

Điều gì xảy ra nếu bạn chỉ khôi phục giao dịch mà bạn hiện đang ném ngoại lệ? – Amber

+0

@Amber: đã không kiểm tra điều đó: ( –

Trả lời

15

Bạn nên kiểm tra xem bạn có đang sử dụng INNODB làm loại cơ sở dữ liệu không. MyISAM không hỗ trợ giao dịch.

+0

"Sự cố" là PDO được cho là sẽ tăng ngoại lệ nếu bạn bắt đầu giao dịch bằng trình điều khiển không hỗ trợ chúng. Bug? Bad docs? – cbednarski

+0

Không có đầu mối. Tất cả những gì tôi biết là đây là một vấn đề đối với tôi khi tôi cố gắng thực hiện các giao dịch bằng PDO với trình điều khiển MySQL, không có trường hợp ngoại lệ nào được ném ra có thể là một lỗi, tôi sẽ phải đọc tài liệu để chắc chắn. Nó xuất hiện nó không phải là một lỗi: Trả về TRUE thành công hoặc FALSE về lỗi.Từ các trang hướng dẫn cho PDO-> beginTransaction –

+0

Tài liệu mà tôi tham chiếu có tại đây: http://us2.php.net/manual/en/pdo.transactions .php – cbednarski

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