OCC and Atomicity | Convex Developer Hub
I have read this article a couple of times, and I think I get it, but I have a scenario I would like to check with you to be sure.
https://docs.convex.dev/database/advanced/occ
I am writing a simple migration setup and it stores each "migration" in a "migrations" table.
Migrations are have unique names ex "2023101901 rename users.name" and are stored in source code.
On each deploy I check which migrations have not been applied yet, and run those in order (if any).
In MongoDB I would create a "migrations" table (collection) where the "name" field has a unique index. Then I simply try to insert each migration, and if they throw (unique index clash) I don't do anything, but if the insert succeed I proceed with the migration. This makes it 100% atomic so I can be sure two (or more) different processes doesn't try to do the migration.
As you can see, it is atomic without locks because I only use a single query (insert) in combination with a unique index.
In Convex, you say I can do just use a "naive approach" with two operations, a read to check if the migration exists, and if it doesn't exists I write the new migration to DB, then do the actual migration?
Would this really be atomic, thread/process safe, bullet proof and safe to do just as in my MongoDB example? If so, epic, but it feels insane (in a good way) so I have to hear you say it first.
Also, how do I think about when the transaction starts/ends? Should I think about each Convex DB function as a transaction?
OCC and Atomicity | Convex Developer Hub
In Queries, we mentioned that determinism
4 Replies
Here is an actual MongoDB example from another project:

In Convex, you say I can do just use a "naive approach" with two operations, a read to check if the migration exists, and if it doesn't exists I write the new migration to DB, then do the actual migration?yes, as long as you do it in the same mutation, data races are impossible
Should I think about each Convex DB function as a transaction?exactly every mutation is an ACID transaction
Don't Drop ACID
When your database supports ACID semantics, you're free to write code the intuitive way and ignore the complexities of concurrency and failure.
Hell yeah, this is so good! 💥
I think it would be awesome if someone added an actual Convex code snippet to https://docs.convex.dev/database/advanced/occ that say just that. Like, "look at this (naive) Convex code, it's within the same mutation, so data races are impossible". Just an idea @ian 😉