Can you please share the full code, along with the error message and result of the query you are running? I tried the code on my end with the python driver and everything works as one expects in case of a transaction, ie. when an error occurred in between the transaction, the customers collection did not have any document account_id: 9. This is the code I ran in pymongo and everything worked as expected, maybe you can try this in your environment:
uri = <your_string_here>
client = pymongo.MongoClient(uri)
db = client.sample_analytics
account = db.accounts
customer = db.customers
with client.start_session() as session:
with session.start_transaction():
account.insert_one({'account_id': 9,'limit': 88888 }, session=session)
account.update_one( { 'account_id':9 }, {'$inc': { 'limit': -100.00 }},session=session)
customer.inserty_one({'name':"vincy5"},session=session) //change to insert_one to make the transaction work
I am simulating if txn failed in between the session it should rollback but it still hold true for syntax error(insertyOne). though for logical error it behaves differently
What @Satyam and @steevej alluded to is that your updateOne() statement is performed outside of the transaction. This is why it appears to do the wrong thing.
In the first example, you need to add the { session } variable into the updateOne() as seen in this Node driver transaction example to signify that this statement is part of the session and thus the transaction.
In the second example, the updateOne() statement contains an error and thus it was not executed. Transaction or not, it makes no difference in this case.
Try to modify your updateOne() to be like account.updateOne( { account_id:00009 }, {$inc: { limit: -100.00 }}, { session }) and it should behave as expected.
It is not. Unlike most SQL-style interactive session, a statement starting a session does not mean that all the subsequent statements are inside that session. In MongoDB, you’ll need to include the session object in the CRUD statement.
As I have mentioned in my earlier reply, you need to modify your updateOne statement to include the session object:
I apologize to exacerbate the confused situation. I was using the example of a Node program (where {session} is required to make the CRUD operation work inside the transaction), and you’re using mongosh and grabbed the database from the Session object as per https://www.mongodb.com/docs/manual/reference/method/Session/#mongodb-method-Session
In scenario 1, I think everything behaved like they should:
start transaction
subtract 100 from account 9
commit transaction
account 9 has limit subtracted by 100 as it should
In scenario 2, there’s a MongoServerError:
start transaction
subtract 100 from account 9
intentionally induce a MongoServerError
transaction aborted
account 9 was not subtracted
Am I following your thought so far correctly?
Basically scenario 2 showed that a MongoServerError would automatically abort a transaction. This is in contrast with your earlier example where you called insertyOne: it resulted in TypeError instead of MongoServerError, so the transaction didn’t auto abort.
Is this the information you’re looking for? Sorry again for the confusion.
So we can conclude that
Scenario 1: MongoDB Perspective its valid since Account :0 don’t exists. But taking a case financial matter were Debit=Credit will fail the business validation. Hence Application has to be intelligent enough to catch modiifiedCount:0 and do a rollback instead of commit.
MongoDB only rollback MongoServerError not TypeError .There also application need to be intellegent enough to do rollback instead of commit