Có thể hữu ích khi xem cách truy vấn này thực sự được thực thi bởi MySQL:
select * from tbl_codes where available = 1 order by rand() limit 1 for update
Thao tác này sẽ đọc và sắp xếp tất cả các hàng phù hợp với WHERE
điều kiện, tạo một số ngẫu nhiên bằng cách sử dụng rand()
vào một cột ảo cho mỗi hàng, sắp xếp tất cả các hàng (trong bảng tạm thời) dựa trên cột ảo đó, sau đó trả lại các hàng cho máy khách từ tập hợp đã sắp xếp cho đến khi LIMIT
đạt được (trong trường hợp này chỉ là một). FOR UPDATE
ảnh hưởng đến việc khóa được thực hiện bởi toàn bộ câu lệnh trong khi nó đang thực thi và do đó mệnh đề được áp dụng khi các hàng được đọc trong InnoDB , không khi chúng được trả lại cho khách hàng.
Bỏ qua những tác động về hiệu suất rõ ràng của những điều trên (thật khủng khiếp), bạn sẽ không bao giờ có được hành vi khóa hợp lý từ nó.
Câu trả lời ngắn gọn:
- Chọn hàng bạn muốn, sử dụng
RAND()
hoặc bất kỳ chiến lược nào khác mà bạn thích, để tìmPRIMARY KEY
giá trị của hàng đó. Ví dụ:SELECT id FROM tbl_codes WHERE available = 1 ORDER BY rand() LIMIT 1
- Khóa hàng bạn muốn bằng cách sử dụng
PRIMARY KEY
của hàng đó chỉ có. Ví dụ:SELECT * FROM tbl_codes WHERE id = N
Hy vọng rằng điều đó sẽ hữu ích.