Progress ABL, Как определить, какой конечный пользователь блокирует запись, и показать другим конечным пользователям, кто блокирует запись?

Я понимаю, что Progress ABL имеет естественную тенденцию делать это:

По умолчанию Progress отображает сообщение: используется on . Подождите или выберите ОТМЕНА, чтобы остановить. (2624)

Это сообщение 2624 предоставляет информацию, но обычно это не то, что нужно, потому что у пользователей нет возможности зафиксировать изменения или продолжить без условия STOP. Затем они возвращаются в процедуру запуска.

Тем не менее, я хочу иметь возможность отображать блокировку записи после того, как если ______ заблокировано, выполните: отображение и конкретная запись заблокирована

Я нашел информацию в статье внизу этого поста об использовании VST _Lock, но документы Progress утверждают это дословно: «Примечание: будьте осторожны при запросе таблицы _Lock; частый доступ может потреблять большое количество системных ресурсов и негативно влиять на производительность. " Есть ли альтернативный подход или лучшая практика для этого? Любая помощь будет принята с благодарностью.

https://knowledgebase.progress.com/articles/Article/P182366


person N8BIZ    schedule 11.06.2018    source источник
comment
Запрашивать _LOCK в продакшене в версиях до 11.4 — очень, очень, очень плохая идея. 11.4 и выше изменили реализацию на моментальный снимок, что делает его менее проблематичным. Но старый код не должен пытаться манипулировать _lock   -  person Tom Bascom    schedule 12.06.2018
comment
Запрос _LOCK хуже, чем кажется kbase. Особенно на производстве. Этот тип кода работает в средах разработки и тестирования и, возможно, в очень небольших производственных средах, но не является хорошей идеей в больших системах.   -  person Tom Bascom    schedule 12.06.2018


Ответы (2)


Я с пониманием отношусь к желанию предоставить пользователю красивое сообщение о том, кто держит блокировку. Но kbase не шутит. Это очень плохая идея использовать _LOCK таким образом.

11.4+ делает его менее плохим, но это все еще очень болезненно для большой производственной системы.

На небольшой системе с размером таблицы блокировки по умолчанию (-L 8192) это будет выглядеть нормально. В большой активной системе с большой таблицей блокировок (обычными являются значения -L к северу от 1M) и большим количеством используемых блокировок вы получите очень, очень разные и очень негативные впечатления.

Лучшим решением может быть просмотр «заблокированных пользователей»:

for each dictdb._Connect no-lock
    where _Connect-usr <> ?
      and _Connect-wait <> " -- ":  /* there are spaces around the '--' */

  display _Connect.

end.

Это будет намного быстрее и может рассказать вам все, что вам нужно знать.

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

etime( yes ).

for each dictdb._Lock where _Lock._Lock-usr <> ? and _Lock._Lock-recid <> ?:

  if etime > 500 then leave.

  /* whatever ... */

end.
person Tom Bascom    schedule 12.06.2018
comment
Спасибо за информацию Том. У меня были опасения по поводу использования _Lock VST. Кроме того, когда я запрашиваю _Connect VST, единственными значениями, которые я извлекаю для поля _Connect-wait, являются -- . Что квалифицируется как значение _Connect-Wait? Это то же самое, что и заблокированный пользователь? Цените любые отзывы. - person N8BIZ; 12.06.2018
comment
Если _Connect-wait = -- соединение ничего не ожидает. Если он чего-то ожидает, то _connect-wait имеет тип ресурса, на котором блокируется сеанс. REC означает блокировку записи. В случае блокировки записи _Connect-wait1 будет содержать RECID. - person Tom Bascom; 12.06.2018
comment
Большое спасибо, сэр! - person N8BIZ; 12.06.2018

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

Запрос _lock может быть не таким уж плохим, как это звучит в комментарии. Вы будете делать это только время от времени, когда пользователь сталкивается с конфликтом блокировки. Также производительность сильно зависит от общего количества заблокированных записей.

Важно правильно запрашивать _lock, в зависимости от версии Progress.

Чтобы повторить мой ответ на аналогичный вопрос:

  • _LOCK всегда имеет полное количество записей, указанное в -L, независимо от того, сколько блокировок существует в настоящее время.
  • В версиях до 11.4 поля не индексируются, но все используемые блокировки находятся в начале таблицы, поэтому вы можете использовать

    FOR EACH _Lock NO-LOCK:
      IF _Lock._Lock-Usr = ? THEN LEAVE.
    

    (_Lock._Lock-Name = ? тоже подойдет). См. http://knowledgebase.progress.com/articles/Article/P161995 (очевидно, на практике это неверно для очень больших таблиц блокировок или большого количества блокировок. Тем не менее, это, вероятно, лучшее, что вы можете сделать, поскольку сканирование всей таблицы блокировок действительно занимает некоторое время.)

  • В версиях 11.4 и 11.5 заполняемые записи больше не находятся в начале, поэтому старый код будет давать неправильные результаты (см. http://knowledgebase.progress.com/articles/Article/000056304, это исправлено в 11.5.1). К счастью, сканирование таблицы блокировок теперь выполняется намного быстрее, поэтому вы можете использовать

    FOR EACH _Lock NO-LOCK WHERE _Lock-Recid <> ?:
    

    упоминается в той же статье. Технически это не реализовано с помощью индексов. (Индекс не будет работать с оператором ‹>.)

  • Начиная с версии 11.5 оба варианта должны работать, но более новый вариант с фразой where должен работать быстрее.
person idspispopd    schedule 12.06.2018
comment
Неправда, что все блокировки ниже первой с _lock-usr = ? до 11.4. Похоже, это верно для небольших тестовых систем. В больших производственных системах вы обнаружите, что это ненадежно. - person Tom Bascom; 12.06.2018
comment
Спасибо за помощь! - person N8BIZ; 12.06.2018
comment
Спасибо за ваш комментарий, Том. Так что база знаний здесь неверна. Тем не менее, это логика, включенная в наше приложение, и, вероятно, лучшее, что вы можете сделать, поскольку сканирование всей таблицы блокировки действительно займет слишком много времени (мы развертываем наше приложение как минимум с -L 100000, вероятно, намного выше в настоящее время с 64-битной базой данных). сервера). - person idspispopd; 13.06.2018