MarkLogic: переключение между базами данных с помощью xdmp.eval

#marklogic #marklogic-9 #marklogic-dhf

#marklogic #marklogic-9 #marklogic-dhf

Вопрос:

Версия MarkLogic: 9.0-6.2

У нас есть пользовательский REST API, который считывает документ из ПРОМЕЖУТОЧНОГО, затем обновляет несколько документов в FINAL, а затем запускает xdmp.documentRemoveCollections в ПРОМЕЖУТОЧНОМ документе.

Шаг 1: Начните с ПРОМЕЖУТОЧНОЙ базы данных. Прочитайте документ

Шаг 2: Переключитесь на КОНЕЧНУЮ базу данных, примените изменения к нескольким документам в КОНЕЧНОЙ базе данных

Шаг 3: Переключитесь на ПРОМЕЖУТОЧНУЮ базу данных, примените xdmp.documentRemoveCollections к документу, прочитанному на шаге 1

Мы используем xdmp.eval для переключения между базами данных, но заметили, что время ожидания службы истекает, вероятно, из-за переключения между базами данных. (например, если мы удалим шаг xdmp.documentRemoveCollections, то служба не будет использовать тайм-аут, вероятно, потому, что ей не нужно переключаться с ОКОНЧАТЕЛЬНОГО на ПРОМЕЖУТОЧНЫЙ)

Мы пытались использовать поток согласования, но поведение не было согласованным, вероятно, из-за нескольких обновлений документа в FINAL.

Пожалуйста, подскажите, следует ли соблюдать какие-либо меры предосторожности в ПОЛЬЗОВАТЕЛЬСКОМ REST API, чтобы избежать тайм-аута при переключении между базами данных взад-вперед.

Заранее спасибо!

Ответ №1:

Тайм-аут в этом случае, вероятно, вызван чтением и записью в один и тот же документ в одной транзакции. На шаге 3 не должно быть необходимости «переключать» базы данных, они уже должны быть в той же базе данных, единственным переключением является шаг 2. Этот рабочий процесс может легко зайти в тупик без особого внимания. Обязательно ли, чтобы шаг 2 был синхронным? если нет, предложите поставить его в очередь на сервер задач. Требуется ли 1,3 для одной транзакции? На шаге 1, скорее всего, заблокированы прочитанные документы, затем на шаге 3 пытаются дождаться освобождения этой блокировки для обновления. Попробуйте принудительно выполнить транзакцию чтения на шаге 1 и убедитесь, что она остается такой до шага 3. Вы можете полностью изолировать их, выполняя ВСЕ шаги во вложенных транзакциях (по отдельности). Рекомендую использовать invoke-функцию (или модуль) поверх eval (со строками) — легко получить поведение «xquery injection» (от друга или врага), используя eval («некоторую строку, которую я создал путем объединения пользовательского ввода»)

Выполняете ли вы это одновременно с другими действиями (одним и тем же вызовом REST или разными вызовами одновременно к одной и той же БД).

Используйте «консоль запросов», чтобы посмотреть, какие транзакции открыты в какое время. Если вы видите «зависание», то почти наверняка обнаружите, что скрывается открытая транзакция.

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

1. Вызываете ли вы eval() на шаге 2 для вызова шага 3? не делайте этого. Лучше вернитесь с шага 2, а затем продолжайте с того места, где вы остановились на шаге 3

2. Большое спасибо за ваш ответ. На шаге 2 у меня есть оценка, указывающая на КОНЕЧНУЮ базу данных, а затем я возвращаюсь к шагу 3. Не могли бы вы помочь пролить некоторый свет на «Попробуйте принудительно выполнить транзакцию чтения на шаге 1 и подтвердите, что она остается такой до шага 3».? Существуют ли конкретные шаблоны поиска, которые не получают блокировку на чтение? Кроме того, если я выполню фиксацию на шаге 2, это снимет блокировки и запустит шаг 3? Или, могу ли я выполнить фиксацию на шаге 3, перед выпуском xdmp.documentRemoveCollections, чтобы освободить любые блокировки? Заранее спасибо!