[JAVA-2967] Dirty reads outside the transaction Created: 10/Sep/18  Updated: 11/Sep/19  Resolved: 11/Sep/18

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

Type: Task Priority: Major - P3
Reporter: Arun Kumar Jain Assignee: Unassigned
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Docker for Mac.


Issue Links:
Related
related to DOCS-12048 Update Transaction Docs: How to avoid... Closed

 Description   

I am using mongodb 4.0 with latest drivers version 3.8.1

Within a transaction, when a value is changed and is not committed yet, outside the transaction we expect to not see that change. This expectation is not happening.

I have written a simple test case to demonstrate this.

 Here is the link to the entire project containing integration test to demonstrate this. It is running mongodb in a docker container, so depends on docker being installed.
https://github.com/arunkjn/mongodbtransactiontest



 Comments   
Comment by Jeffrey Yemin [ 14/Sep/18 ]

The sample code here has no explicit abort because each attempt to run the transaction uses a different ClientSession, and closing the ClientSession automatically aborts any uncommitted transaction. If you are trying to re-use the ClientSession for each attempt, you will have to explicitly abort.

Comment by Arun Kumar Jain [ 14/Sep/18 ]

One thing I observed is that when using java driver, when gettig a Transient Transaction error and retrying the transaction, we have to explicitly abort it. Otherwise we get a 'IllegalStateException - transaction already in progress' when we start it on retry.

If we dont explicitly abort and dont start as well when retrying, we get transaction aborted on server error. This is not in sync with the javascript examples given at https://docs.mongodb.com/master/reference/method/Session.startTransaction/#Session.startTransaction.

I can demonstrate this with a test case if you need. Please let me know.

Comment by Arun Kumar Jain [ 14/Sep/18 ]

Thanks Jeff. It is definitely enlightening and cleared a lot of questions for me.

Comment by Jeffrey Yemin [ 11/Sep/18 ]

Hi Arun,

Transactions in MongoDB use snapshot isolation, which don't prevent stale reads. This is not specific to MongoDB. Most modern databases work this way.

Here's a part of a presentation which talks about conflicts, specifically around reads: https://www.youtube.com/watch?v=3x_Pf9rQGCo&t=905s. You may find it illuminating.

We think though that we can do a better job explaining this in our online documentation, so DOCS-12048 has been created to address that.

I'm going to close this ticket now, as the driver and server are working as designed, but please let us know if we can be of further assistance. Thanks for the feedback.

Comment by Arun Kumar Jain [ 11/Sep/18 ]

Thanks Jeff. I have updated the code with another test case which checks for stale read inside transaction which will lead to a dirty write. Currently this test case is not passing.

 

Comment by Jeffrey Yemin [ 10/Sep/18 ]

Yes, that's correct: all operations within the transaction should be passed the ClientSession instance on which the transaction is started.

This is documented in the manual, which is linked to from the What's New section of the Java driver documentation.

 

Comment by Arun Kumar Jain [ 10/Sep/18 ]

Hi Jeff,

Yes doing that solves the problem for me. I feel this should be documented better at http://mongodb.github.io/mongo-java-driver/3.8/driver/

So, all the collection operations which have to be included in the transaction similarly need session object?

Comment by Jeffrey Yemin [ 10/Sep/18 ]

Hi arunkjn

The update operation doesn't happen within the transaction unless you pass the ClientSession to the replaceOne call here, as in:

collection.replaceOne(session, Filters.eq("name", "arun"), person2

 

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