Как правильно использовать метод восстановления ресурсов JTA? - PullRequest
0 голосов
/ 06 марта 2020

Я пытаюсь понять, как правильно вызвать метод javax.transaction.xa.XAResource.recovery(int). Я имею дело со средой, в которой я вручную вызываю операции XA и не имею диспетчера ресурсов контейнера.

JavaDocs просто говорит, что возможны значения флагов TMSTARTRSCAN, TMENDRSCAN и TMNOFLAGS , но не предоставляйте объяснения того, что происходит, когда используются какие-либо из этих флагов или их комбинации.

Я прочесал код Glassfi sh для того, что они могут делать со значениями флага, но не сделал Там нет ничего полезного. Я посмотрел на Артемиду - она ​​будет возвращать все незавершенные транзакции, только когда используется одинокий флаг TMSTARTRSCAN. Postgres JDB C почти такой же, за исключением того, что TMSTARTRSCAN может быть связан с TMENDRSCAN, все также возвращается в одном вызове.

Я предполагаю, что причина наличия флагов есть чтобы обеспечить какую-то нумерацию результатов, если вокруг слишком много незавершенных транзакций. Таким образом, правильный способ справиться с этим:

  • вызов recover() с TMSTARTRSCAN
  • вызов recover() с TMNOFLAGS до тех пор, пока полученный массив не станет пустым
  • вызов recover() с TMENDRSCAN

Для всех вышеперечисленных вызовов будьте готовы обработать возвращенные значения XID.

Но я бы с удовольствием указал или дал объяснение того, как это должно было функционировать.

ОБНОВЛЕНИЕ

Когда @kayaman изящно указал мне на спецификацию XA из X / Open, я вижу, что моё предположение, вероятно, было верным. Стандарт объясняет предполагаемое поведение намного более четко, но он не применяется один к одному для реализации Java из-за разницы в ожидаемых размерах массива. Стандарт объясняет, когда не следует звонить recover(TMENDRSCAN), но в случае Java неясно, и неясно, может ли неправильный вызов вызвать исключение.

1 Ответ

0 голосов
/ 10 марта 2020

Эта функция JTA особенно неинтуитивна, так как многие тонкости проектирования базового C API из XA spe c были убиты при переводе на Java из-за не совсем правильного предположения, что они были не важны на языке, который автоматически управляет памятью.

Во-первых, важно уточнить, работаете ли вы с точки зрения менеджера транзакций, компонента, который фактически вызывает метод восстановления, или менеджера ресурсов, компонента который реализует это. Glassfi sh - это TM, Artemis и Postgres - RM.

Вызовы TM восстанавливаются в стиле итерации, начиная с TMSTARTRSCAN (откройте новый итератор, получите первый пакет результатов), опционально с TMNOFLAGS (проверяйте дальнейшие пакеты результатов, пока один не вернется пустым, указывая, что конец достигнут) и завершив работу с TMENDRSCAN (закройте итератор, позволяя RM освободить имеющиеся у него элементы). На практике количество сомнительных ветвей / Xids достаточно мало, чтобы они формировали только один пакет, поэтому многие TM просто вызовут TMSTARTRSCAN, а затем непосредственно TMENDRSCAN, или даже сделают оба в одном вызове. Теоретически это может пропустить некоторые сомнительные ветки, но обычно работает достаточно хорошо, поскольку цикл вызова периодически повторяется, и любые дополнения будут просто выбраны на следующем проходе.

RM реализует восстановление как стабильный курсор / итератор, чтобы он соответствовал требованиям, чтобы во время итерации вещи не слишком сильно менялись. Несмотря на то, что он может по желанию разделить сомнительную ветвь tx на пакеты, например, чтобы минимизировать использование памяти в драйвере, это не является общей оптимизацией по причинам, изложенным выше.

...