Is _creationTime guaranteed unique?
I've understood this to be true, but read in a post here (I can't find it now) something that hinted at this maybe not being a 100% guarantee. I have logic that relies on this value being unique, so just wanted to make sure.
4 Replies
nope, not guaranteed. also not guaranteed to be monotonic, although both of these properties are usually true.
by not monotonic, i mean it's possible to have:
1. cron job mutation reads the maximum
_creationTime
in table1 as 1000 and saves this in table2 as {cursor: 1000}
2. a user calls a mutation which inserts a document with _creationTime
of 999 to table1.
3. the cron job runs again, reading the cursor from table2 and reads documents in table1 with _creationTime > 1000
, and finds no documents.
the cron job is trying to process all documents by cursoring on _creationTime
, but it missed a document. you can avoid these race conditions by adding serialization to the table.
when we originally shipped _creationTime
we did have uniqueness and monotonicity guarantees, but it caused a lot of unnecessary contention because to guarantee it we needed to make mutations run in sequence; they couldn't run in parallelSuper helpful, thank you. Can you say a bit more (or point to something that says more) on adding serialization to a table?
Or are you just talking about not doing parallel writes in my mutations
Even if I did that, there's no guarantee that two different users won't have mutations commit at the same time to a single table. For example, I have plaid updates coming in via webhook, collisions between these and not having the ordered/unique guarantees on creationTime are my current concern.
for sure. the typical way of serializing writes to a table is having an incrementing field. so something like
this mutation takes a read dependency on the
[maxCounter, infinity)
range of the tbl.counter
index, and then inserts at maxCounter + 1
. Two mutations that insert into "tbl" can't read the same value for maxCounter
and then both commit, because that wouldn't be serializable. So now you have maxCounter
as a unique monotonic value that you can use for cursoring or whatever. But it also means mutations can't insert concurrently into "tbl".
if you just want uniqueness, not monotonicity, I would use the _id
field (although you can do something similar with a counter that checks that the exact counter value doesn't exist before inserting)Okay, that makes sense, thanks for the explanation here.