Issues Mongodb transactions Pessimistic locking

I found that when two transactions modify a document concurrently, the transaction executed later will return a write conflict error
Is there any way to make the later executed transaction continue to wait instead of interrupting the execution?

Since the original intention of using mongo is because it can store more data than MySql, I found that if I have many fields, it is easy to write conflicts.

If I want to write less conflicts, I need to split it into multiple collections.

I saw that the official document suggests to use the driver to retry the transaction.
The behavior of retrying transactions means that mongo cannot be used to develop business easily, and it seems that the requirements for developers are higher.

For example, inventory business, inventory balance needs to be changed frequently, which means that I need to put the change logic in front of the business. . . It seems to be highly intrusive to the business code. . .

I’m in a dilemma. This makes me feel that using mongodb will make development costs more and more difficult to maintain. Compared to the case of using MySql, although I really want to use mongodb

It is using Google Translate, please don’t mind if there is any disrespectful sentence

I believe this setting supposed to make it wait: https://docs.mongodb.com/manual/reference/parameters/#mongodb-parameter-param.maxTransactionLockRequestTimeoutMillis, but when I tried it with mongodb 5.0, it did not work: second transaction still fails.

Hi @111674, and welcome to the forums!

As you have discovered, with the help of the Drivers API you could write an application logic to retry the transaction.

Applications should take measures to handle errors during transaction commits and incorporate retry logic for transactions. The MongoDB drivers API for transactions have been designed to provide developers with more control over the logic.

Not all transaction commit attempts could / should be retried. There are cases where an application logic requires a failed commit to be aborted and not retried. i.e. to avoid a duplicate, etc.

Please see Transaction Error Handling for more information.

I don’t quite understand the above. However if you are having issues with the transactions retry logic mixing with the business logic in your applications, I’d suggest to create abstraction layers and structure the code so that there is higher level logic for the business logic.

Regards,
Wan.

1 Like

Hi @Dmitriy_Shirokov,

I would suggest to open a new thread/post with the following information:

  • Minimal code to reproduce the issue
  • The error (i.e. failure) that you see
  • Your expectation on how it should have worked

Regards,
Wan.

Hi, @wan, I did open new post: Parameter max Transaction Lock Request Timeout Millis is not working, and I will add code to reproduce there

@wan, retrying transaction will not work for write conflict, it only works for things like network errors. In case of write conflict they say retry whole transaction.
I tried that in perf tests with Java code and spring Retriable and it is inefficient (as compared with a custom app-level synchronization on a global “mutex”).
DBs like mySQL, Oracle wait (efficient wait, not retries) for row to be unlocked, this is standard DB behavior. If one transaction updates property A on a document, and another transaction updates property B, there is no conflict (think git merge) or at least such conflict can be auto-resolved, and it would be in mySQL. I think this is what @Recall complains about.

Hi @Dmitriy_Shirokov ,

Please incorporate your own retry logic to handle different cases, and see Transaction Error Handling for more information.

The following resources may help in understanding concurrency in MongoDB (in/out of transactions):

Regards,
Wan.