Không, giao dịch không theo dõi nếu một câu lệnh SQL đơn không thành công.
Nếu một câu lệnh SQL đơn không thành công thì câu lệnh được khôi phục (giống như được mô tả trong Câu trả lời của @ eggyal) - nhưng giao dịch vẫn đang mở. Nếu bạn gọi commit
bây giờ, không có khôi phục các câu lệnh thành công và bạn vừa chèn dữ liệu "bị hỏng" vào cơ sở dữ liệu của mình. Bạn có thể tái tạo điều này một cách dễ dàng:
m> CREATE TABLE transtest (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL DEFAULT '',
CONSTRAINT UNIQUE KEY `uq_transtest_name` (name)) ENGINE=InnoDB;
Query OK, 0 rows affected (0.07 sec)
m> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
m> INSERT INTO transtest (name) VALUE ('foo');
Query OK, 1 row affected (0.00 sec)
m> INSERT INTO transtest (name) VALUE ('foo');
ERROR 1062 (23000): Duplicate entry 'foo' for key 'uq_transtest_name'
m> INSERT INTO transtest (name) VALUE ('bar');
Query OK, 1 row affected (0.00 sec)
m> COMMIT;
Query OK, 0 rows affected (0.02 sec)
m> SELECT * FROM transtest;
+----+------+
| id | name |
+----+------+
| 3 | bar |
| 1 | foo |
+----+------+
2 rows in set (0.00 sec)
Bạn thấy rằng việc chèn 'foo' và 'bar' đã thành công mặc dù câu lệnh SQL thứ hai không thành công - bạn thậm chí có thể thấy rằng AUTO_INCREMENT
-giá trị đã được tăng lên do truy vấn bị lỗi.
Vì vậy, bạn phải kiểm tra kết quả của từng query
-call và nếu không thành công, hãy gọi rollback
để hoàn tác các truy vấn thành công khác. Vì vậy, mã của Lorenzo trong hướng dẫn sử dụng PHP có ý nghĩa.
Lỗi duy nhất buộc MySQL khôi phục giao dịch là "giao dịch bế tắc" (và đây là lỗi dành riêng cho InnoDB, các công cụ lưu trữ khác có thể xử lý các lỗi đó theo cách khác).