[JAVA-528] Question about WriteConcern and Java driver concurrency using "update if current" Created: 01/Mar/12  Updated: 11/Sep/19  Resolved: 01/Mar/12

Status: Closed
Project: Java Driver
Component/s: Connection Management
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Major - P3
Reporter: Chris Cho Assignee: Unassigned
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Hello,

I am attempting to implement an "update if current" strategy with the MongoDB Java driver and had a couple questions. Our system reads and writes concurrently to Mongo and it is important that we avoid dirty reads. Here are the questions I had while implementing it since it's not that trivial to test at this point:

1) Do I need to use the requestStart and requestDone methods for the Mongo connection for this strategy? If I was not guaranteed to be using the same connection, the threads could be reading or attempting the update on either the master or slave which means there is a window of opportunity during which an update could still be accepted since the changes made by the thread on another connection have not been propagated yet. Here's an example:

Thread_A reads message X from connection to Mongo_M
Thread_B reads message X from connection to Mongo_S
Thread_A updates some fields, creating message Y. Thread_A sends update details on Mongo_S.
Thread_B updates some fields, creating message Z. Thread_B sends update details on Mongo_M.
Mongo_S propagates data (message Y) to Mongo_M (contains message Z).

2) If in my update in the "update if current" strategy (I am using the WriteConcern.SAFE option), is a Java exception thrown if an error condition occurs during the update?

Any assistance would be appreciated, thanks.



 Comments   
Comment by Jeffrey Yemin [ 01/Mar/12 ]

OK, closing this then.

Comment by Chris Cho [ 01/Mar/12 ]

That makes sense since the writes are routed to the master, thanks.

Comment by Jeffrey Yemin [ 01/Mar/12 ]

For this particular use case, it might be better to use http://www.mongodb.org/display/DOCS/findAndModify+Command.

Comment by Chris Cho [ 01/Mar/12 ]

Hi Jeff,

Thanks for clearing up that writes are routed to the master. I am following the "update if current" strategy on the Atomic Operations page to prevent threads from competing over the same document. Here are some details of my implementation, can you take a look and see if my strategy is correct?

1) Retrieve one document with findOne() with criteria of

{"status": "unprocessed"}

.
2) Extract _id and status field and package into a query.
3) Create an update query using atomic "$set" and

{"status" :"processing"}

.
4) Run an update on the collection using the new query and update query with WriteConcern.SAFE level and upsert=false.
5) Catch MongoException which I'm assuming is thrown when the update cannot go through since there are no documents that match.

Comment by Jeffrey Yemin [ 01/Mar/12 ]

Is "Mongo_M" the master, and "Mongo_S" the slave in your example? If so, it can't happen as you describe, as all writes are routed to the master.

But even given that all writes go the master, it is possible for one thread to overwrite another threads changes to the same document if they don't coordinate the activity in some way. There are a number of features that can help you, depending on the nature of those updates. To get started you can look at:

http://www.mongodb.org/display/DOCS/Atomic+Operations

Also, as implied on that page, you can never have a "dirty read" in MongoDB in the way that you may be thinking from RDBMS.

Generated at Thu Feb 08 08:52:30 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.