Câu trả lời là không - mu88 mu88 casino

/imgposts/w1u3xcn2.jpg

Sau khi đã đọc hai bài viết trước về chủ đề này, tôi cảm thấy cần thiết phải đi sâu phân tích thêm về cách thức hoạt động của các loại khóa trong hệ quản trị cơ sở dữ liệu MySQL. Thực tế, trong quá trình thảo luận về hiện tượng "đọc hồn ma" (phantom read) ở phần trước, có một điều kiện quan trọng mà tôi chưa đề cập đến.

Chẳng hạn như câu truy vấn đơn giản SELECT * FROM bang1 WHERE id = 1 sẽ không áp dụng bất kỳ kiểu khóa nào nổi tiếng cả, trừ khi chúng ta đang sử dụng mức cô lập giao dịch RR (Repeatable Read) hoặc RC (Read Committed). Theo tài liệu chính thức của MySQL:

Câu lệnh SELECT ... FROM thực hiện một phép đọc nhất quán (consistent read), lấy một bản chụp ảnh (snapshot) của cơ sở dữ liệu và không đặt bất kỳ khóa nào, trừ khi mức độ cô lập giao dịch được đặt là SERIALIZABLE. Với mức độ cô lập SERIALIZABLE, thao tác tìm kiếm sẽ đặt khóa chia sẻ tiếp theo (shared next-key locks) trên các bản ghi chỉ mục mà nó gặp phải. Tuy nhiên, đối với các câu lệnh khóa dòng bằng chỉ mục duy nhất để tìm kiếm một hàng duy nhất, chỉ yêu cầu khóa bản ghi chỉ mục.

Như vậy, kiểu đọc nhất quán này thực chất làm việc dựa trên cơ chế read view, ngoại trừ trường hợp mức cô lập giao dịch là SERIALIZABLE.

Tuy nhiên, có một số tình huống đặc biệt mà MySQL sẽ áp dụng khóa, cụ thể là:

  • SELECT * FROM bảng WHERE ? LOCK IN SHARE MODE;
  • SELECT * FROM bảng WHERE ? FOR UPDATE;
  • INSERT INTO bảng VALUES (...);
  • UPDATE bảng SET ? WHERE ?;
  • DELETE FROM bảng WHERE ?;

Trong đó, chỉ có câu lệnh đầu tiên sử dụng khóa S (khóa chia sẻ), còn lại đều sử dụng khóa X (khóa bóng đá ngoại hạng anh trực tiếp hôm nay độc quyền).

Khóa S đại diện cho khóa chia sẻ, trong khi khóa X đại diện cho khóa độc quyền. Các khóa S không xung đột với nhau, nhưng khóa S sẽ mu88 mu88 casino xung đột với khóa X và ngược lại. Ngoài ra, hai khóa X cũng luôn xung đột lẫn nhau.

Ở mức cô lập RC, hiện tượng "đọc hồn ma" (phantom read) có thể xảy ra. Trong khi đó, ở mức cô lập RR, hiện tượng này bị ngăn chặn nhờ việc áp dụng các khóa gap thích hợp trong các trường hợp nhất định.

Vậy có phải tất cả các câu lệnh trong mức cô lập RR đều cần sử dụng khóa gap hay không? Câu trả lời là không. Chẳng hạn, giả sử bạn đang làm việc với một bảng bang1 có trường khóa chính id. Khi thực hiện bóng đá trực tiếp câu lệnh sau:

1SELECT * FROM bang1 WHERE id = 10 FOR UPDATE;

Câu hỏi đặt ra là liệu câu lệnh này có cần sử dụng khóa gap hay không? Câu trả lời là không, bởi vì đây là một chỉ mục khóa chính và chỉ có thể tồn tại duy nhất một bản ghi thỏa mãn điều kiện id = 10.

Tuy nhiên, nếu trường id không phải là khóa chính mà chỉ là một chỉ mục duy nhất (unique index), thì sao? Lúc này, chúng ta cần áp dụng cả khóa record (trên bản ghi tương ứng) và khóa gap (nếu cần). Lý do là vì chỉ mục duy nhất đảm bảo rằng chỉ có một bản ghi duy nhất thỏa mãn điều kiện id = 10, nhưng vẫn cần kiểm tra thêm bản ghi liên kết qua chỉ mục phụ (secondary index).

Nếu trường id không phải là chỉ mục duy nhất mà chỉ là một chỉ mục thông thường, thì lúc này khóa gap trở nên cần thiết. Điều này nhằm đảm bảo rằng không có hiện tượng "đọc hồn ma" xảy ra trong quá trình giao dịch.

Giả sử chúng ta có một bản ghi với id = 10 và muốn đảm bảo rằng không có hiện tượng "đọc hồn ma". Chúng ta cần áp dụng ba khóa gap trên chỉ mục id, nhưng không cần áp dụng khóa gap trên chỉ mục khóa chính, vì bản ghi tương ứng đã được khóa qua cơ chế record lock.