I have photos collection like this
[
{
"id": "1",
"imageOrder": 1,
"userId":"1",
"imageUrl": "url1"
},
{
"id": "2",
"userId":"1",
"imageOrder": 2,
"imageUrl": "url2"
},
{
"id": "3",
"userId":"1",
"imageOrder": 3,
"imageUrl": "url3"
}
]
here
- id is mongo Id
- imageOrder is the order in which the image should be displayed in the UI
- imageUrl is the url of the image
- userId is the id of the user to whom this image belongs to
I have an endpoint that allows user to delete his/her photo, logic roughly works like below
lets say you want to delete 2nd image in the above example,
- find all photos of requesting user
- re-order rest of the image(ex: if you are deleting 2nd image, 3rd image’s imageOrder will become 2)
- use bulkWrite to update imageOrders for the rest of the images and delete the 2nd image.
- final snapshot would look like this
[{id:1,imageOrder:1},{id:3,imageOrder:2}]
I noticed an unpredictable behaviour, if 2 parallel calls are made to the delete api for the same user
ex:
-
delete call to image 1 and 2 is triggered by the user
-
both delete 1 and 2 would have read all 3 images to memory using find call
-
call to delete image 1 would have
[{id:2,imageOrder:1},{id:3,imageOrder:2}]
in memory -
call to delete image 2 would have
[{id:1,imageOrder:1},{id:3,imageOrder:2}]
in memory
now which even is updating the DB last will be persisted.
the expected behaviour is that you have only [{id:3,imageOrder:1}]
in the collection.
I tried using transactions with sessions but dint seem to help.
How do i Achieve this?
PS:
using mongo atlas v5.0.14