How to Verify Updates?

50 views
Skip to first unread message

Mike Craig

unread,
Oct 9, 2012, 6:00:28 PM10/9/12
to mongod...@googlegroups.com
How can I verify that an update call actually updates a document?

So far I've tried using getN on the writeResult, but it sometimes returns 0 when a document was actually updated.

This is a sharded and replicated cluster (3 shards w/ 1 primary and 1 secondary each), and the application is highly parallel with lots of updates to this collection.

Cheers,
Mike

Jenna deBoisblanc

unread,
Oct 10, 2012, 3:07:20 PM10/10/12
to mongod...@googlegroups.com
Hello Mike,

How are you confirming that the document was updated when getN() returns 0? Would it be possible to post one of the update commands in question, and ideally, the results of getLastError()? Is it possible that multiple threads are attempting to update the same document?

Mike Craig

unread,
Oct 10, 2012, 4:07:19 PM10/10/12
to mongod...@googlegroups.com
> How are you confirming that the document was updated when getN() returns 0?

The updates include both timestamps and datapoint-specific IDs. So I'll do an update to DOC_ID with TIMESTAMP and DATA_ID, then get 0 from getN, and then lookup DOC_ID and see TIMESTAMP and DATA_ID there anyway. I can verify via our app logs that we're not processing the same DATA_ID multiple times simultaneously (i.e. this is not a race condition amongst multiple instances of the same DATA_ID).

Would it be possible to post one of the update commands in question, and ideally, the results of getLastError()?

This will require some logging changes.

> Is it possible that multiple threads are attempting to update the same document?

Yes, that is the point here. Let me elaborate: there are many app threads finding and then updating documents in the same mongo collection, so we use a "persisted_at" timestamp to avoid overwrites. It looks something like this (excuse my pseudocode; the actual app code doesn't lend itself to user list emails):

    doc = coll.find({"_id":some_id})
    persisted_at = doc.persisted_at

    do_something(doc); // Do some work, update the document in memory
    doc.persisted_at = Time.now()

    result = coll.update({"_id":doc.id, "persisted_at":persisted_at},doc)

    if (result.getN() == 0)
        // Abort and retry because the update condition wasn't found

So in short, I'm trying to use conditional updates and getN() calls to avoid losing data when two workers are updating a single document simultaneously.

Mike


--
You received this message because you are subscribed to the Google
Groups "mongodb-user" group.
To post to this group, send email to mongod...@googlegroups.com
To unsubscribe from this group, send email to
mongodb-user...@googlegroups.com
See also the IRC channel -- freenode.net#mongodb

Jenna deBoisblanc

unread,
Oct 11, 2012, 2:40:12 PM10/11/12
to mongod...@googlegroups.com
Hi Mike,

I want to confirm that I understand your question and observations; please let me know if I am mistaken-
When you issue an update on a document, the server returns writeResult 0 to the thread that performed the update. You can confirm that the thread is responsible for the update because each thread has a unique DATA_ID.  Here is my understanding of the situation in pseudocode:     

{code}
{_id: x, TIMESTAMP: t0, DATA_ID: d0}

doc = find({_id: x})
time = doc.TIMESTAMP = t0
do_something(doc)
doc = {_id: x, TIMESTAMP: t1, DATA_ID: d1}
result = coll.update({_id:x, TIMESTAMP: t0}, doc)

getN() returns 0
find({_id: x}) -> {_id:x, TIMESTAMP: t1, DATA_ID: d1}
{code}

If my understanding is correct, could you tell us what driver you're using? Are you using writeResult.safe, or are you calling getLastError() manually? Can you confirm that there's no way another thread could have been responsible for this write- any chance the same DATA_ID is being used more than once? Additional information about the way DATA_ID is generated would be helpful.

On Tuesday, October 9, 2012 6:01:02 PM UTC-4, Mike Craig wrote:
Reply all
Reply to author
Forward
0 new messages