2013-05-02 133 views
1

我在當前項目中遇到了mongo更新問題。我們在MongoDB中維護了一個文檔池。閱讀器進程從該池中提取一批文檔。爲了確保來自DB的文檔不被再次提取,與每個文檔相關聯的狀態被改變(例如,從已到達到正在處理)。是否有可能在MongoDB中進行原子批量更新?

我們正在考慮擴大規模,並有多個讀取器進程撿起不同的批次。但是,根據我的理解,mongo更新在批處理中不是原子的。是否有任何方法可以實現這一目標?我需要以確保文檔在被前一個文檔更新之前不會被另一個讀取器從池中提取出來。我基本上是在查看原子批處理更新。 謝謝!

回答

1

想必你正在做這樣的事情來更新雕像:

db.docs.update({status:"arrived"},{$set:{status:"processing"}},{multi:true}) 

,然後用狀態文件的加載:「處理」。

目前沒有mongo咒語來更新多於一個但少於所有匹配的文件。您對所有文件使用{multi:true},或者您只標記一個文件。

鑑於此,您可以嘗試使用非多重更新爲每個讀者進程標記具有唯一標識的到達文檔。然後閱讀文檔進行處理。標記將用一個閱讀器的唯一ID自動更新一個文檔,從而避免閱讀器之間的爭用。

喜歡的東西:

db.docs.update({status:"arrived"},{$set:{status:"processing", readerId:<myid>}}) 

其中<myid>是價值的讀取器進程發出此蒙戈更新的唯一ID。如果你使用findAndModify你可以找到原子和更新文檔 db.docs.find({status:"processing", readerId:<myid>}}

+0

感謝您的答案,但我不認爲這將解決問題。我的問題是,我希望批處理中的所有文檔的狀態可以自動更改並添加readerId似乎不處理該問題。 – Tazo 2013-05-02 05:07:06

+0

隨着更新的全部或部分行爲,標記時批量大小爲1,或者所有新文檔都將發送給一個閱讀器。 – grogers 2013-05-02 14:55:59

+0

在http://docs.mongodb.org/manual/faq/concurrency/的第二次閱讀中,我想說當多個線程使用相同的查詢發出更新語句時,結果將不甚明瞭。這些線程將爭奪文檔,並且這將取決於什麼線程在yield之後獲得寫入鎖定。 mongo上有一個開放的問題來支持限制更新:https://jira.mongodb.org/browse/SERVER-1599。 – grogers 2013-05-02 15:23:04

0

然後讀者可以加載文檔。

如果

db.docs.findAndModify({ 
    query : {'status':'arrived' }, 
    sort: { dateTimeOfdoc:-1}, 
    update : { 'status':'processing','transactionId':12345}, 
    new : true}); 

雖然所有線程都爲文檔競爭,因爲每個文件可以發現在原子操作修改,這意味着一旦一個線程有它,它不會被別人獲取。

這不是你想要的一批文檔,但是它能處理你的問題嗎?