2011-08-15 28 views
6

Giả sử tôi viết một ứng dụng mà tôi cần nhận thông báo trong thời gian thực từ máy chủ và giả sử các thông báo đó được lưu trữ trên cơ sở dữ liệu mysql. Đối với tôi để có được chúng tôi sẽ phải bỏ phiếu cho máy chủ mysql (tiếp tục lặp lại cùng một truy vấn chọn cho đến khi tôi thực sự nhận được kết quả), nhưng con số đó là cách rất hiệu quả khi thực hiện nó vì phần lớn thời gian chọn lên trống. Nếu tôi làm điều đó thường nó là không hợp lý căng thẳng trên máy chủ nếu tôi làm điều đó hiếm khi các thông báo sẽ đến trong rất muộn. Vì vậy, tôi đã tự hỏi nếu có một cách để nói một truy vấn mysql để chặn cho đến khi một kết quả phù hợp với một điều kiện trở nên có sẵn.Có cách nào để MySQL chờ hàng phù hợp với điều kiện được chèn

list = query ("SELECT * FROM `notifications` WHERE `unread`=1") ; 

thay vì trả lại một danh sách trống nếu không có thông báo chưa đọc, nó thay vào đó sẽ chờ đợi cho đến khi có thực sự là những thông báo chưa đọc để chuyển

Trả lời

8

tôi khuyên bạn nên sử dụng các mô hình producer consumer, thực hiện với một bảng mới như "hàng đợi công việc". Không cần thiết cho một thủ tục được lưu trữ, bởi vì kích hoạt rất đơn giản.

  1. Trình kích hoạt sẽ điền hàng đợi công việc
  2. Mã sẽ thăm dò bảng xếp hàng công việc. Bởi vì bảng sẽ rất nhỏ, truy vấn sẽ nhanh và tải thấp.
  3. Mã sẽ làm bất cứ điều gì bạn cần và xóa dòng trong bảng khi kết thúc - giữ nó càng nhỏ càng tốt

Tạo một bảng với id của notification để được xử lý và một cột "trạng thái xử lý", ví dụ:

create table work_queue (
    id int not null auto_increment, 
    notification_id int references notifications, 
    status enum ('ready', 'processing', 'failed') 
); 

Tạo trình kích hoạt đơn giản mà populates một bảng hàng đợi công việc:

delimiter $ 
create trigger producer after insert on notifications 
for each row begin 
    insert into work_queue (notification_id, status) 
    select new.id, 'ready' 
    where new.unread; 
end; $ 
delimiter ; 

cá tuyết của bạn e sẽ có mã giả:

  1. select * from work_queue where status = 'ready' order by id limit 1
  2. update work_queue set status = 'processing' where id = <row.id>
  3. Hãy làm những gì bạn cần phải notifications where id = <row.notification_id>
  4. hoặc delete from work_queue where id = <row.id> hoặc update work_queue set status = 'failed' where id = <row.id> (bạn sẽ phải tìm ra những gì để làm với mục thất bại)
  5. Ngủ 1 giây (tạm dừng này cần phải giống như tốc độ đến tối đa của thông báo - bạn sẽ cần phải điều chỉnh điều này để cân bằng giữa kích thước work_queue và tải trên máy chủ)
  6. goto 1.

Nếu bạn có một quá trình bỏ phiếu, không cần phải lo lắng về khóa. Nếu bạn có nhiều quy trình bỏ phiếu, bạn sẽ cần phải xử lý các điều kiện chủng tộc.

+0

ý tưởng thú vị, tôi mang nó không có cách nào khác ngoài việc bỏ phiếu, cảm ơn vì ancwer :) –

+0

không có cách nào khác, vì vậy bạn muốn làm cho cuộc thăm dò của bạn càng nhanh càng tốt.Tôi phải nói, đó là 10 điểm uy tín nhất mà tôi từng kiếm được :) – Bohemian

+0

tôi cho rằng việc sử dụng bảng bộ nhớ có thể là một sự tăng cường tốt ở đây –