Search code examples
gemfiregeode

Geode transaction to generate ID and insert object


Let's say I have 3 PARTITIONED_REDUNDANT regions:

  • /Orders - keys are Longs (an ID allocated from /Sequences) and values are instances of Order
  • /OrderLineItems - keys are Longs (an ID allocated from /Sequences) and values are instances of OrderLineItem
  • /Sequences - keys are Strings (name of a sequence), values are Longs

The /Sequences region will have many entries, each of which is the ID sequence for some persistent type of that is stored in another region (e.g., /Orders, /OrderLineItems, /Products, etc.)

I want to run a Geode transaction that persists one Order and a collection of OrderLineItems together.

And, I want to allocate IDs for the Order and OrderLineItems from the entries in the /Sequences region whose keys are "Orders" and "OrderLineItems", respectively. This operates like an "auto increment" column would in a relational database - the ID is allocated/assigned at insertion time as part of the transaction.

The insertion of Orders and OrderLineItems and the allocation of IDs from the /Sequences region need to be transactionally consistent - they all succeed or fail together.

I understand that Geode requires data being operated on in transaction to be co-located if the region is partitioned.

The obvious thing is to co-locate OrderLineItems with the owning Order, which can be done with a PartitionResolver that returns the Order's ID as the routing object.

However, there's still the /Sequences region that is involved in the transaction, and I'm not clear on how to co-locate that data with the Order and OrderLineItems.

The "Orders" entry of the /Sequences reqion would need to be co-located with every Order for which an ID is generated...wouldn't it? Obviously that's not possible.

Or is there another / better way to do this (e.g., change region type for /Sequences)?

Thanks for any suggestions.


Solution

  • Depending on how much data is in your /Sequences region - you could make that region a replicated region. A replicated region is considered co-located with all other regions because it's available on all members.

    https://geode.apache.org/docs/guide/15/developing/transactions/data_location_cache_transactions.html

    This pattern is potentially expensive though if you are creating a lot of entries concurrently. Every create will go through these shared global sequences. You may end up with a lot of transaction conflicts, especially if you are getting the next sequence number by incrementing the last used sequence number.

    As an alternative you might want to consider UUIDs as the keys for your Orders and OrderLineItems, etc. A UUID takes twice as much space as a long, but you can allocate a random UUID without needing any coordination between concurrent creates.