Single-node transaction with user code

I’m having the following order of code execution and a single-node db:

1)update/insert/delete a single document in a collection
2)write/delete a single file is located on FS

These operations depend on each other.

In case the second operation ( FS one ) fail, then I have inconsistency: document is in collection, file is not on FS.

Would it be a good pattern to rely on the transaction:

  • abort the transaction created on the first operation when the second operation fails
  • and commit the transaction if the second operation succeeds ?

Hi @Alex_Krt welcome to the community!

In my opinion, it depends on which one is the source of truth in your app. If your app depends on the database, then deleting the information from the database basically erases it from existence. Sure if the 2nd FS step failed for some reason, you’ll have some orphaned file, but I think this is less bad compared to the other way around: the app thinks the file still exists, but in reality it cannot find it in the FS anymore. This could lead to crashes. You can then at your leisure scan and remove files that exists in FS but not in the database.

I feel like this approach may be easier to manage vs. using transactions, since you don’t have to deal with yet another failure mode: what if something happened during the transaction (network hiccup, app crash, database crash, etc.) and the transaction failed to commit, while the file is already gone in FS? Then you’re basically back to square 1, only this time, inside a transaction :slight_smile:

Obligatory disclaimer: this is my opinion only. It may be totally useless for you and your use case.

Best regards