2012-03-19 29 views
1

我有一個mysql表,我存儲了要處理的作業。主要是原始數據的文本字段將需要大約一分鐘的時間來處理。mysql行級讀鎖取代消息隊列

我有兩臺服務器從該表中提取數據,然後刪除它。

要管理我目前使用亞馬遜SQS的兩臺服務器之間的作業分配。我存儲了所有需要在SQS中處理的行IDS,工作服務器輪詢SQS以獲取新行。

該系統目前正常工作,但SQS增加了一層複雜性和成本,我覺得這些太過複雜了,無法實現我所做的。

我想實現無SQS同樣的事情,不知道是否有什麼辦法可以讀鎖定的行,這樣,如果一個工人正在一排,沒有其他的工人可以選擇該行。或者如果有更好的方法來做到這一點。

回答

1

一個簡單的解決方法:在作業表中添加一列,is_taken_by INT

然後在你的員工,你做這樣的事情:

select job_id from jobs where is_taken_by is null limit 1 for update; 
update jobs set is_taken_by = worker_pid where id = job_id; 

SELECT ... FOR UPDATEsets exclusive locks on rows it reads。這樣你可以確保沒有其他工人能夠完成同樣的工作。

注意:您必須在顯式事務中運行這兩行。

使用SELECT FOR UPDATE用於更新行的鎖,只有當自動提交被禁用應用(無論是開頭START TRANSACTION事務或自動提交如果啓用自動提交設置爲0,符合規範的行不會被鎖定。

+0

添加行的問題是,如果工作人員在中途失敗,該行將被卡在表中並處於正在處理的狀態......我將閱讀更多關於'for update'的信息,具體取決於如何它鎖定它排了多長時間,它可能會解決這個問題 – applechief 2012-03-19 18:59:22

+0

添加另一列:'locked_at DATETIME'和運行週期的cronjob來解鎖被鎖在很久以前行。 – 2012-03-19 19:06:49