Tôi có một giải pháp thiết thực cho bạn, một giải pháp mà tôi đã thấy được thực hiện trong một dự án tại nơi làm việc của tôi. Thay vì chỉ sử dụng 0 và 1 cho chưa hoàn thành và đã hoàn thành, hãy mở rộng tập hợp của bạn để bao gồm nhiều trường hợp hơn.
Hãy gọi cột đó là trạng thái . Dưới đây là các giá trị khác nhau của cột đó và các trạng thái tương ứng của công việc.
- Khi trạng thái là 0, công việc chưa được thực hiện bởi bất kỳ chuỗi công nhân nào.
- Khi trạng thái là 1, công việc đã được chọn bởi một chuỗi công nhân và đang được xử lý.
- Khi trạng thái là 2, công việc không thành công. (Bạn nên xem xét khả năng xảy ra lỗi trong quá trình xử lý.)
- Khi trạng thái là 3, công việc đã hoàn thành.
Các luồng của bạn phải chứa logic sao cho nó chỉ chọn các công việc có trạng thái là 0 và thay đổi trạng thái thành 1. Điều này sẽ không cho phép các luồng khác nhận các công việc đang được xử lý. Khi công việc hoàn thành, trạng thái được đặt thành 3 và nếu công việc không thành công, trạng thái được đặt thành 2. Sau đó, chuỗi có thể tiếp tục và tìm kiếm công việc khác vẫn đang được hoàn thành.
Bạn cũng có thể yêu cầu các chuỗi xem xét chọn các công việc ở trạng thái 2, nhưng bạn sẽ phải xác định logic để chỉ định số lần thử lại hữu hạn.
CHỈNH SỬA:
Sau một cuộc thảo luận dài , chúng tôi tình cờ tìm ra giải pháp cùng nhau. Câu trả lời ở trên của tôi là tốt ở một trạng thái tổng quát hơn khi 'công việc' là một quá trình cần một thời gian để hoàn thành. Nhưng đó không phải là trường hợp của vấn đề của OP.
Vì vậy, giải pháp cuối cùng đã hoạt động là:
BEGIN
SELECT * FROM Jobs WHERE JobID = (SELECT * FROM Jobs WHERE completed = 0 LIMIT 1) LOCK IN SHARE MODE;
UPDATE Jobs SET completed = 1 WHERE JobID = (PREVIOUS ID);
COMMIT;