2011-10-12 25 views
6

Ví dụ, tôi có một hàng với một cột C1 value = 'clean', và hai khách hàng khác nhau chạy truy vấn này tại đồng thời:Các câu lệnh mysql đơn có nguyên tử trong MyISAM và InnoDB không?

update T1 set C1 = 'dirty' where Id = 1 

Nếu không sử dụng các giao dịch, là nó đảm bảo bất kể loại động cơ rằng giá trị của mysql_affected_rows() sẽ là 1 cho một khách hàng và 0 cho một khách hàng khác?

+1

Nếu bạn cần nguyên tử, nhưng không muốn sử dụng các bảng InnoDB, [xem bảng khóa MySQL] (http://dev.mysql.com/doc/refman/5.1/en/lock-tables.html) – bobobobo

Trả lời

11

Có và Không :-)

Trong cả hai trường hợp, access is serialised (giả sử bạn đang sử dụng một động cơ giao dịch như InnoDB) kể từ khi họ nhấn cùng hàng, vì vậy họ sẽ không can thiệp với nhau. Nói cách khác, các câu lệnh nguyên tử.

Tuy nhiên, số lượng hàng bị ảnh hưởng thực sự phụ thuộc vào bộ cấu hình của bạn khi bạn mở kết nối. Các page for mysql_affected_rows() đã này để nói (đậm của tôi):

Đối với câu lệnh UPDATE, bị ảnh hưởng-hàng giá trị mặc định là số lượng hàng thực sự thay đổi. Nếu bạn chỉ định cờ CLIENT_FOUND_ROWS cho mysql_real_connect() khi kết nối với mysqld, giá trị hàng bị ảnh hưởng là số hàng "tìm thấy"; có nghĩa là, khớp với mệnh đề WHERE.

Và từ the mysql_real_connect page:

CLIENT_FOUND_ROWS: Trả lại số tìm thấy hàng (phù hợp), không phải là số thay đổi hàng.

Vì vậy, về những gì xảy ra vớiCLIENT_FOUND_ROWS được cấu hình, hàng bị ảnh hưởng cho:

UPDATE T1 SET C1 = 'dirty' WHERE id = 1 

để làm với việc dữ liệu được thay đổi, chỉ những gì hàng phù hợp. Đây sẽ là 1 cho cả hai truy vấn.

Mặt khác, nếu CLIENT_FOUND_ROWSkhông đặt, truy vấn thứ hai sẽ không thực sự thay đổi hàng (vì nó đã được điền bằng 'bẩn') và sẽ có số hàng bằng 0.

Nếu bạn muốn hành vi cùng bất kể thiết lập đó (chỉ thay đổi hiển thị), bạn có thể sử dụng một cái gì đó như:

UPDATE T1 SET C1 = 'dirty' WHERE id = 1 AND C1 <> 'dirty' 
+0

Bạn có ý nói rằng các bản cập nhật một lần không phải là nguyên tử cho MyIASM? – Pacerier

+0

Một google nhanh chóng cho thấy rằng MyISAM chủ yếu là nguyên tử miễn là bạn không bao giờ giết một chuỗi hoặc truy vấn. http://bugs.mysql.com/bug.php?id=51193 –

+0

@sanmai: Từ http://dev.mysql.com/doc/refman/5.5/en/innodb-locks-set.html: Khóa đọc, một UPDATE hoặc DELETE thường thiết lập các khóa ghi trên mỗi bản ghi chỉ mục được quét trong việc xử lý câu lệnh SQL. – paxdiablo

3

MySQL là ACID tuân thủ nếu bạn sử dụng một công cụ lưu trữ giao dịch như InnoDB.

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