2012-05-14 9 views
6

Tôi có một câu hỏi liên quan đến giao dịch và giao dịch mysql.mysql cam kết và giao dịch

Tôi có một vài câu lệnh php thực thi truy vấn mysql.

Tôi chỉ cần nói những điều sau đây?

mysql_query("START TRANSACTION"); 
//more queries here 
mysql_query("COMMIT"); 

Chính xác điều này sẽ làm gì? Nó giúp như thế nào? Đối với các cập nhật, xóa và chèn, tôi cũng tìm thấy điều này để chặn các truy vấn khác không đọc được:

mysql_query("LOCK TABLES t1 WRITE, t2 WRITE"); 
//more queries here 
mysql_query("UNLOCK TABLES t1, t2"); 

Điều này có thể chặn các truy vấn khác về bản chất hoặc chỉ ghi/chọn không?

Một câu hỏi khác: Nói một truy vấn đang chạy và chặn các truy vấn khác. Truy vấn khác cố truy cập dữ liệu bị chặn - và nó thấy rằng nó bị chặn. Làm thế nào nó tiến hành? Liệu nó có chờ cho đến khi dữ liệu được bỏ chặn một lần nữa và tái thực hiện truy vấn? Liệu nó chỉ thất bại và cần được lặp lại? Nếu vậy, làm thế nào tôi có thể kiểm tra?

Cảm ơn rất nhiều!

Dennis

+0

Bạn đang sử dụng các bảng InnoDB hoặc MyISAM? – Daan

+0

@ Tôi có thể sử dụng InnoDB – weltschmerz

Trả lời

12

Trong InnoDB, bạn không cần phải bắt đầu một cách rõ ràng hoặc giao dịch cuối cho các truy vấn duy nhất nếu bạn chưa thay đổi các thiết lập mặc định của autocommit, đó là "on". Nếu tự động bật, InnoDB sẽ tự động bao quanh mọi truy vấn SQL đơn lẻ trong một giao dịch, tương đương với START TRANSACTION; query; COMMIT;.

Nếu bạn sử dụng rõ ràng START TRANSACTION trong InnoDB với tự động bật, thì bất kỳ truy vấn nào được thực hiện sau khi một tuyên bố START TRANSACTION sẽ được thực hiện hoặc tất cả các lệnh sẽ không thành công. Điều này rất hữu ích trong môi trường ngân hàng, ví dụ: nếu tôi chuyển 500 đô la vào tài khoản ngân hàng của bạn, hoạt động đó chỉ nên thành công nếu số tiền đã được trừ khỏi số dư ngân hàng của tôi và được cộng vào số dư của bạn. Vì vậy, trong trường hợp này, bạn sẽ chạy một cái gì đó như

START TRANSACTION; 
UPDATE customers SET balance = balance - 500 WHERE customer = 'Daan'; 
UPDATE customers SET balance = balance + 500 WHERE customer = 'Dennis'; 
COMMIT; 

Điều này đảm bảo rằng cả hai truy vấn sẽ chạy thành công hoặc không, nhưng không chỉ một. This post có một số thông tin khác về thời điểm bạn nên sử dụng giao dịch.

Trong InnoDB, bạn rất hiếm khi phải khóa toàn bộ bảng; InnoDB, không giống như MyISAM, hỗ trợ khóa cấp hàng. Điều này có nghĩa là khách hàng không phải khóa toàn bộ bảng, buộc các khách hàng khác phải đợi. Khách hàng chỉ nên khóa các hàng họ thực sự cần, cho phép các khách hàng khác tiếp tục truy cập vào các hàng họ cần.

Bạn có thể đọc thêm về giao dịch InnoDB here. Câu hỏi của bạn về bế tắc được trả lời trong các phần 14.2.8.814.2.8.9 tài liệu. Nếu một truy vấn thất bại, trình điều khiển MySQL của bạn sẽ trả về một thông báo lỗi cho biết lý do; sau đó ứng dụng của bạn sẽ phát hành lại các truy vấn nếu cần.

Cuối cùng, trong mã mẫu của bạn, bạn đã sử dụng mysql_query. Nếu bạn đang viết mã mới, vui lòng ngừng sử dụng thư viện cũ, chậm và không được sử dụng mysql_ cho PHP và sử dụng mysqli_ hoặc PDO thay thế :)

+0

tuyệt vời, cảm ơn bạn! Vậy InnoDB có tự động khóa các hàng không? Và làm thế nào tôi có thể kiểm tra xem bảng của tôi có tự động cam kết không?và làm thế nào tôi có thể thiết lập một chỉ mục trên nó (Tôi đang sử dụng phpmyadmin) – weltschmerz

+0

Bạn có thể đưa ra một truy vấn 'HIỂN THỊ VARIABLES LIKE 'autocommit'', hoặc bấm vào' biến' trên trang chủ phpMyAdmin. Việc tạo chỉ mục được thực hiện bằng cách vào cơ sở dữ liệu và bảng thích hợp, nhấp vào 'cấu trúc' và sử dụng biểu mẫu bạn thấy ở đó để tạo chỉ mục. Hoặc bạn có thể đưa ra các câu lệnh SQL, ví dụ: 'Bảng ALTER TABLE THÊM INDEX (trường)'. Tôi không chắc chắn những gì bạn có nghĩa là bởi "không InnoBD tự động chỉ khóa hàng" - nó chắc chắn sẽ không bao giờ tự động khóa toàn bộ bảng, nếu đó là những gì bạn có nghĩa là :) – Daan

+0

Autocommit bật :) Làm các phím chính luôn luôn phục vụ như một chỉ mục? Tôi có các khóa chính trong bảng của tôi và muốn thêm chỉ mục nhưng nó cho biết nó chỉ có thể giống như khóa chính ... – weltschmerz