2011-10-14 2 views
3

Можно ли достичь взаимоблокировок на операциях MongoDb upsert? Я выполнение нагрузки теста на операции upsert, которая выглядит как:MongoDb Upsert Deadlock

db.update(
    { foo: {a: 'xxx', b: 'yyy'}, $lt: {"order.date": someDate}}, 
    {order: order}, 
    true, false); 

развернутых на Лазурном машине с официальным водителем MongoDB C#. Единый экземпляр, никаких наборов реплик или осколок.

Когда я запустил 5000 этой же команды обновления, разделите ее на 200 одновременных потоков (по 2 машины по 100 нитей), большую часть времени они будут заканчиваться взаимоблокировками. То есть многие из вызовов никогда не возвращаются. Я вижу из db.currentOp() через консоль, многие обновления все еще существуют, застряли в заблокированном: true, с lockType: 'write'.

Почему этот тупик случается? Как это возможно? И как я могу это предотвратить? Существуют ли какие-либо конкретные рекомендации о том, какие операции следует избегать, чтобы избежать взаимоблокировок на монгодбе?

Является ли $ атомным, связанным с решением? Я даже не знаю, как установить $ atomic: true на C#, хотя это, вероятно, не имеет отношения к этой проблеме взаимоблокировки.

+0

Упсерт - это операция обновления? – sll

+0

это обновление с флагом upsert, установленным в true – Sheepy

ответ

0

$atomic should help

db.update(
    { 
     $and: [ 
      { foo: { a: 'xxx', b: 'yyy' }, 
      { $lt: { 'order.date': someDate } } 
     ], 
     $atomic: true 
    }, 
    { order: order }, 
    true, 
    false 
); 

также, вы можете в $ и п. проверьте свои пояснения для своего звонка, чтобы узнать, какие индексы используются и т. д.

Смежные вопросы