Can Foundation DB / Record Layer support a sequence?

Hi ,
is there any way to use a “senesce” object on FoundationDB ?
implement "select nextval " or increment a long counter and get number as an atomic operation ?

in Record layer ( Java ) its the equivalent to AtomicLong incrementAndGet() API.

Thanks.

Hi,

You can either use:

  1. atomic operations as you described to keep track of your sequence,
  2. an Index.MAX_EVER_LONG on your field using the record-layer ,
  3. Versionstamp (you can have a look at @scgray’s explanation with :apple::strawberry:)

I think Versionstamp is the way to go if you just want something like a SQL sequence, as this will avoid a READ operation.

Pierre,
Thanks for the tips, I will try them starting with bullet 3

1 Like

Just for some background: due to the way that FDB’s optimistic transaction implementation works, it’s very difficult to implement a generalized atomic “increment and get” on a single value (efficiently–i.e., without sacrificing concurrency). The way FDB transactions are implemented, they buffer all mutations locally and only send the mutations in a single batch to the database at commit time. During a transaction’s execution, the mutations inserted in that transaction are made visible to other reads conducted within the same transaction by reading from a local cache, but other transactions cannot see the updates because they haven’t even been sent to the database servers. That means that to do something like a “increment and get” operation in line in the middle of a transaction, you’d have to somehow introduce an alternative commit/update path (at least for those operations) to ensure that each value given out was unique, and I think it would be fairly complicated to fit in with the way the rest of FDB is architected.

That being said, there’s a fairly easy implementation of unique atomic increment that’s just not very efficient–simply read a key (or record), increment its value by 1 in the same transaction, and then commit. (Note: the value you read isn’t guaranteed to be unique until you commit the transaction.) The cost is that this will conflict (i.e., fail to commit) with any other transaction that tries to increment the same key, so you can’t have any concurrency (or put another way, the increment-key is an effective semaphore). So it is usually something to avoid if you need high throughput, but for certain low contention applications that require keys incrementing by 1, it may be workable.

If you need a monotonically increasing value but don’t necessarily need to read the value during the operation, you can do something like use versionstamps to generate the sequence ID as @PierreZ suggests, or use something like the MAX_EVER_LONG on a field “plus a random amount” to generate vaguely monotonically increasing sequence numbers with medium contention. There are some more details here: FoundationDB Record Layer FAQ

2 Likes