Đúng rồi. Các hàng trong bảng đang được đọc từ đó bị khóa bằng khóa dùng chung (SELECT
ngầm định là LOCK IN SHARE MODE
). Không có cách nào để tránh điều này. Đó là những gì bạn đang yêu cầu hệ thống:sao chép tất cả các hàng phù hợp với một điều kiện. Cách duy nhất để đảm bảo rằng trên thực tế, tất cả các hàng phù hợp với điều kiện và danh sách đó không thay đổi trong hoặc ngay sau khi thực hiện câu lệnh đó, là khóa các hàng.
Để làm rõ về lý do tại sao bạn không thể INSERT
với group_id = 2
:
Điều này liên quan đến truy vấn của bạn cụ thể là WHERE group_id = 3 AND created < '2014-01-04'
trên KEY group_id_created (group_id, created)
. Để tìm kiếm tất cả các hàng khớp với group_id = 3 AND created < '2014-01-04'
chỉ mục sẽ được duyệt ngược lại bắt đầu từ hàng đầu tiên vượt quá điều kiện đó, giới hạn trên là (3, '2014-01-14')
và tiếp tục cho đến khi tìm thấy một hàng không phù hợp với điều kiện do created
không có giới hạn dưới sẽ là hàng đầu tiên trong đó group_id < 3
tất nhiên là group_id = 2
.
Điều đó có nghĩa là hàng đầu tiên gặp phải group_id = 2
cũng là bị khóa, đây sẽ là hàng có created
giá trị. Điều này sẽ khiến bạn không thể INSERT
vào "khoảng cách" giữa (2, MAX(created))
và (3, MIN(created))
(tất nhiên không phải là SQL thích hợp, chỉ là SQL giả), mặc dù đây không phải là "khóa khoảng cách" cụ thể.