#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, чтобы освободить любые блокировки? Заранее спасибо!