2014-05-25 14 views
6

Tài liệu PHP PDO::commit() nói rằng phương thức trả về TRUE thành công hoặc FALSE khi lỗi. Điều này có nói đến sự thành công hay thất bại của việc thực hiện câu lệnh giữa beginTransaction() và commit() không?PDO :: commit() thành công hay thất bại

Ví dụ, từ các tài liệu:

$dbh->beginTransaction(); 
$sql = 'INSERT INTO fruit (name, colour, calories) VALUES (?, ?, ?)'; 
$sth = $dbh->prepare($sql); 

foreach ($fruits as $fruit) { 
    $sth->execute([ 
     $fruit->name, 
     $fruit->colour, 
     $fruit->calories, 
    ]); 
} 

$dbh->commit(); 

Nếu bất kỳ hành trên thất bại, sẽ phương pháp() cam kết trả về false vì "tất cả-hoặc-không có gì cơ sở" giao dịch nguyên tử?

+0

Tôi không thực sự nhớ là cần phải cam kết trong mã cơ sở, bạn đã thử làm điều đó mà không có nó? – Jonast92

+0

Tôi không chắc mình hiểu.Điểm giao dịch thủ công là để đảm bảo rằng nhiều câu lệnh đều thành công hoặc không có. –

+0

Tôi nghĩ rằng bạn đang suy nghĩ quá mức. Nếu một trong những thất bại trong kịch bản này thì rất có thể tất cả sẽ thất bại và ngược lại. Chỉ cần thêm xử lý lỗi thích hợp vào mã và nếu bạn thực sự lo ngại về những gì không thành công thì chỉ cần đăng nhập nó. Tôi đã không bao giờ phải sử dụng cam kết trong mã phía máy chủ, tôi thấy nó không chắc rằng bạn phải. – Jonast92

Trả lời

2

Giá trị trả về dựa trên pdo :: cam kết chính nó, không phải giao dịch bạn đang cố thực hiện. Nó trả về FALSE khi không có giao dịch nào hoạt động, nhưng nó không rõ ràng bất cứ khi nào nó trả về TRUE hoặc FALSE.

Các truy vấn được thực hiện trong chính giao dịch sẽ thành công hoặc không thành công trên chính giao dịch đó. Sử dụng ví dụ của Mr.Tk, giao dịch sẽ được thực hiện nếu có thể và không xảy ra lỗi trong khi thực hiện truy vấn trong khối "thử" và cuộn lại nếu xảy ra lỗi trong khối "thử".

Khi chỉ đánh giá các truy vấn được thực hiện trong khối "thử", cá nhân tôi sẽ cố gắng nắm bắt PDOException thay vì Ngoại lệ bình thường.

$dbh->beginTransaction(); 
try { 
    // insert/update query 
    $dbh->commit(); 
} catch (PDOException $e) { 
    $dbh->rollBack(); 
} 
0

Tôi đã luôn luôn thực hiện nó như thế:

$dbh->beginTransaction(); 

try { 
    // insert/update query 

    $dbh->commit(); 
} catch (Exception $e) { 
    $dbh->rollBack(); 
} 

Và luôn luôn làm việc như sự quyến rũ! :)

Vì vậy, tôi nghĩ rằng trong trường hợp của bạn nếu chèn sẽ thất bại ứng dụng nên ném một ngoại lệ và cam kết thậm chí sẽ không kích hoạt.

3

Phần quan trọng là thiết PDO trong chế độ ngoại lệ, trong khi có try-catch duy nhất để làm một rollback là không cần thiết. Do đó, mã của bạn là được rồi, không cần phải thay đổi nó nếu tất cả các bạn muốn là rollback về thất bại, miễn là bạn có dòng này ở đâu đó:

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

Trong trường hợp thất bại kịch bản sẽ được chấm dứt, kết nối đóng và mysql sẽ vui lòng quay lại giao dịch cho bạn.

Trong trường hợp bạn vẫn muốn khôi phục thủ công, bạn nên làm đúng cách, không giống như được nói trong các câu trả lời khác. Hãy chắc chắn rằng

  • bạn đang bắt Exception, không PDOException, vì nó không có vấn đề gì đặc biệt ngoại lệ hủy bỏ việc thực hiện
  • bạn tái ném một ngoại lệ sau khi rollback, để được thông báo về vấn đề
  • cũng là một công cụ bảng hỗ trợ các giao dịch (ví dụ cho Mysql nó phải là InnoDB, không phải MyISAM).

Danh sách kiểm tra này được lấy từ my article mà bạn có thể thấy hữu ích trong điều này hoặc nhiều khía cạnh khác.

+0

Bạn có thực sự chắc chắn về điều này? Nếu tôi thực hiện 10 lần chèn hoặc cập nhật khác nhau, và trong lần cuối cùng, bạn có thể đưa ra một ngoại lệ, tất cả 9 câu khác đều được khôi phục? –

+0

Tôi đồng ý với @CarlosGoce: nó sẽ không khôi phục mà không xử lý 'bắt đầu/rollback' rõ ràng. Nhưng ngoại lệ sẽ giúp chạy 'rollback' như được nêu bởi @ Mr.TK. Trong thực tế, bạn thậm chí không trả lời câu hỏi về 'commit': các giao dịch rất hữu ích nếu bạn muốn hủy bỏ nhiều truy vấn được gửi trước đó nếu có điều gì sai. – Yvan

+0

@Yvan chắc chắn nó sẽ rollback như một giao dịch sẽ luôn luôn được cuộn lại tại một * kết nối đóng *. Nhưng tôi thà đồng ý rằng với các giao dịch thử bắt là hữu ích, nếu được sử dụng đúng cách. –

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