1. 程式人生 > >php出現往mongodb中寫入順序與實際寫入順序不一致的的情況

php出現往mongodb中寫入順序與實際寫入順序不一致的的情況

如果你查詢mongodb中某個集合查詢條件中恰巧有一項時順序遞增的值(類似mysql中的自增主鍵欄位),且按這個值的範圍查詢,而又恰巧排序所用的欄位為_id,那麼此時程式碼查詢返回的結果在部分情況下會有問題,即會漏掉某些記錄。

以下面兩段程式碼為示例來說明

$resultOne= Feeds::find([
                [
                    'uuid' => ['$gt' => (int)$lastTid],
                    'isdelete' => 0,
                ],
                'sort' => ['uuid' => -1],
            ]);


$resultTwo = Feeds::find([
                [
                    'uuid' => ['$gt' => (int)$lastTid],
                    'isdelete' => 0

                ],
                'sort' => ['_id' => -1],
            ]);

其中$lastTid為上次查詢結果中uuid為最大的值,可以理解和php中用microtime(true)生成的值的意義一樣。

$resultOne變數返回的結果不會漏掉某些結果,比如有一組uuid從大到小的值為2097935,2097934,2097933,2097932,2097931這五項值,$resultOne會正常返回這五項的值。


但是$resultTwo在部分情況下會出現查詢到了2097935和2097931,但沒有查詢到2097934,2097933,2097932這三項。原因是什麼呢?

原因是由於uuid在觸發寫入feeds前是嚴格按遞增的順序已生成好的,但如果併發量高的情況下,先生成的uuid最終並不一定先寫入feeds集合中,即在同一時刻,在同一個for迴圈中往mongodb中寫入單條記錄,先執行的寫記錄請求的並不一定先寫入mongodb中,最終視mongodb寫入的情況而定,例如:

for($i=0 $i<10; $i++) {
    $this->mongo->feeds->insert(['uuid' => $uuid, 'isdelete' => 0]);
}
上面的就有可能出現第$i=8條比第$i=5條先寫入到feeds集合中,這種情況並不是每次都會出現,而是偶爾會出現。

結論就是php呼叫php的mongo擴充套件往mongodb中寫入資料時與最終實際寫入的順序有可能不一樣。