Транзакция Geode для генерации идентификатора и вставки объекта

#gemfire #geode

#gemfire #geode

Вопрос:

Допустим, у меня есть 3 РАЗДЕЛЕННЫХ_ОСНОВНЫХ региона:

  • /Orders — это длинные ключи (идентификатор, выделенный из /Sequences), а значения являются экземплярами Order
  • /OrderLineItems — ключи являются длинными (идентификатор, выделенный из /Sequences), а значения являются экземплярами OrderLineItem
  • /Sequences — ключи представляют собой строки (имя последовательности), значения имеют длину

В области /Sequences будет много записей, каждая из которых представляет собой последовательность идентификаторов для некоторого постоянного типа, который хранится в другом регионе (например, /Orders , /OrderLineItems, /Products и т. Д.)

Я хочу запустить транзакцию Geode, которая сохраняет один заказ и коллекцию элементов OrderLineItems вместе.

И я хочу выделить идентификаторы для Order и OrderLineItems из записей в области /Sequences, ключами которых являются «Orders» и «OrderLineItems» соответственно. Это работает как столбец «автоматического увеличения» в реляционной базе данных — идентификатор выделяется / присваивается во время вставки как часть транзакции.

Вставка Orders и OrderLineItems и выделение идентификаторов из области /Sequences должны быть согласованными с точки зрения транзакций — все они завершаются успешно или завершаются неудачей вместе.

Я понимаю, что Geode требует, чтобы данные, обрабатываемые в транзакции, были совместно расположены, если область разделена.

Очевидным является совместное размещение OrderLineItems с порядком владения, что можно сделать с помощью PartitionResolver, который возвращает идентификатор заказа в качестве объекта маршрутизации.

Тем не менее, все еще существует область /Sequences, которая участвует в транзакции, и я не совсем понимаю, как совместить эти данные с элементами Order и OrderLineItems.

Запись «Orders» в запросе /Sequences должна быть расположена рядом с каждым заказом, для которого генерируется идентификатор…не так ли? Очевидно, что это невозможно.

Или есть другой / лучший способ сделать это (например, изменить тип региона для /Sequences )?

Спасибо за любые предложения.

Ответ №1:

В зависимости от того, сколько данных находится в вашем регионе / Sequences, вы можете сделать этот регион реплицируемым регионом. Реплицируемая область считается расположенной совместно со всеми другими регионами, поскольку она доступна для всех участников.

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

Этот шаблон потенциально дорогостоящий, если вы создаете много записей одновременно. Каждое создание будет проходить через эти общие глобальные последовательности. В итоге может возникнуть множество конфликтов транзакций, особенно если вы получаете следующий порядковый номер путем увеличения последнего используемого порядкового номера.

В качестве альтернативы вы можете использовать UUID в качестве ключей для ваших Orders и OrderLineItems и т. Д. UUID занимает в два раза больше места, чем long, но вы можете выделить случайный UUID без необходимости какой-либо координации между одновременными созданиями.

Комментарии:

1. Я переключил refid для области /Sequences в моем cache.xml из PARTITION_REDUNDANT для РЕПЛИКАЦИИ. После этого я вижу следующую ошибку: Исключение в потоке «main» org.apache.geode.cache. Исключение TransactionDataRebalancedException: транзакционные данные перемещены из-за перебалансировки. Должен ли я повторять транзакцию в цикле? Или каков способ обработки этой ошибки?

2. Существует небольшая сложность, с которой вам приходится сталкиваться при смешивании реплицированных и разделенных областей в транзакции. Первая операция в транзакции должна попасть в разделенную область, чтобы установить узел транзакции. Я подозреваю, что, возможно, ваша первая операция была с реплицированной областью, поэтому вы получили эту ошибку. Ссылка, которую я разместил выше, упоминает об этом, хотя я чувствую, что в этом вопросе не совсем ясно.