блокировка записи

Обсуждение вопросов по разработке программ в среде продуктов копорации "Progress Software"
Аватара пользователя
svr
Старожил
Сообщения: 68
Зарегистрирован: 13 июл 2001, 03:00

Re: Проверка блокировки

Сообщение svr » 22 июл 2002, 10:24

FD писал(а):Зачем вы так изголяетесь, чтобы проверить, захвачена запись или нет?

По условиям задачи процедура проверки залоченности записи сама НЕ ДОЛЖНА БЛОКИРОВАТЬ эту запись. Выше я довольно подробно объяснял, почему такое ограничение. Поэтому предложенный вариант не подходит. Если два юзеря таким CAN-FINDом поставят на одну и ту же запись SHARE-LOCK (а они смогут это сделать), то ни один из них не сможет апгрейдить блокировку до EXCLUSIVE-LOCK.

Аватара пользователя
dmi
Старожил
Сообщения: 1523
Зарегистрирован: 27 сен 2001, 03:00
Откуда: Москва
Контактная информация:

Re: Проверка блокировки

Сообщение dmi » 22 июл 2002, 13:09

svr писал(а):
FD писал(а):Зачем вы так изголяетесь, чтобы проверить, захвачена запись или нет?

По условиям задачи процедура проверки залоченности записи сама НЕ ДОЛЖНА БЛОКИРОВАТЬ эту запись. Выше я довольно подробно объяснял, почему такое ограничение. Поэтому предложенный вариант не подходит. Если два юзеря таким CAN-FINDом поставят на одну и ту же запись SHARE-LOCK (а они смогут это сделать), то ни один из них не сможет апгрейдить блокировку до EXCLUSIVE-LOCK.


btw: CAN-FIND lock'ов не ставит. Прочти в help подробнее.

/dmi

Аватара пользователя
svr
Старожил
Сообщения: 68
Зарегистрирован: 13 июл 2001, 03:00

re:блокировка записи

Сообщение svr » 22 июл 2002, 13:44

По документации вроде не должен лочить... Но вот пример.

Код: Выделить всё

do transaction:
    message "transaction 1 start" view-as alert-box.  /*1*/
    do transaction:
        if can-find(first userconf share-lock no-wait) then
            message "lock success" view-as alert-box. /*2*/
        else
            message "lock failed" view-as alert-box.
    end.
    message "transaction 1 end" view-as alert-box.    /*3*/
end.
message "end" view-as alert-box.                      /*4*/

Запускаем и смотрим промоном. На мессаге /*1*/ локов нет. Нас мессаге /*2*/ ЕСТЬ. На мессаге /*3*/ (субтранзакция кончилась) ТОЖЕ ЕСТЬ. На /*4*/ уже нет - кончилась транзакция.
Что же имееют в виду, когда пишут, что can-find не лочит записи? :(

Аватара пользователя
dmi
Старожил
Сообщения: 1523
Зарегистрирован: 27 сен 2001, 03:00
Откуда: Москва
Контактная информация:

re:блокировка записи

Сообщение dmi » 23 июл 2002, 09:17

svr писал(а):По документации вроде не должен лочить... Но вот пример.

Код: Выделить всё

do transaction:
    message "transaction 1 start" view-as alert-box.  /*1*/
    do transaction:
        if can-find(first userconf share-lock no-wait) then
            message "lock success" view-as alert-box. /*2*/
        else
            message "lock failed" view-as alert-box.
    end.
    message "transaction 1 end" view-as alert-box.    /*3*/
end.
message "end" view-as alert-box.                      /*4*/

Запускаем и смотрим промоном. На мессаге /*1*/ локов нет. Нас Что же имееют в виду, когда пишут, что can-find не лочит записи? :(


Мы посмотрели -:

1. Второй оператор TRANSACTION не дает ничего, кроме WARNING'а при компиляции
2. CAN-FIND с SHARE-LOCK'ом действительно лочит запись, но сразу же ее отпускает, т.е. can-find = find + release, и, как следствие, если делать это в транзакции, то остается limbo-lock, который видно в PROMON'е. Это поведение, в принципе, даже логично.

Спросите Потемкина в support?

/dmi

new
Старожил
Сообщения: 32
Зарегистрирован: 28 мар 2002, 03:00

re:блокировка записи

Сообщение new » 02 сен 2002, 14:15

Возможно ли снять блокировку записи (др. пользователя ) програмно.
не прибегая к утилите PROMON

Аватара пользователя
dmi
Старожил
Сообщения: 1523
Зарегистрирован: 27 сен 2001, 03:00
Откуда: Москва
Контактная информация:

re:блокировка записи

Сообщение dmi » 02 сен 2002, 14:55

new писал(а):Возможно ли снять блокировку записи (др. пользователя ) програмно.
не прибегая к утилите PROMON


Можно снять, если пользователя, который залочил запись, от базы отстрелить.
;)
PS: Promon блокировки только показывает. Или ты resolve limbo-lock?

/dmi

new
Старожил
Сообщения: 32
Зарегистрирован: 28 мар 2002, 03:00

re:блокировка записи

Сообщение new » 03 сен 2002, 15:00

promon только смотрит?! при всем моем уважении к вашему опыту.
у promonа есть функция disconnect user.

можно ли по-подробнее про "пользователя, который залочил запись, от базы отстрелить"

не какой я вам не "resolve limbo-lock" :-Р

Аватара пользователя
dmi
Старожил
Сообщения: 1523
Зарегистрирован: 27 сен 2001, 03:00
Откуда: Москва
Контактная информация:

re:блокировка записи

Сообщение dmi » 03 сен 2002, 15:12

new писал(а):promon только смотрит?! при всем моем уважении к вашему опыту.
у promonа есть функция disconnect user.
можно ли по-подробнее про "пользователя, который залочил запись, от базы отстрелить"
не какой я вам не "resolve limbo-lock" :-Р


Так disconnect user - это как топором головную боль лечить.

А про программное отключение пользователя - логичное решение от PSC ;). Хотя, как мне намекал системный администратор - не единственное.

Kbase Id:
21135

Title:
How To Do a Remote proshut Using Virtual System Tables (VST)

Creation:
02-Jul-2001

Modified:
02-Jul-2001

SUMMARY:

Some customers have asked how to proshut a user remotely. This
Knowledge Base Solution provides an example of how to do this using
the Virtual System Tables (VST). The sample code will run on Progress
Version 8.2 and higher.

EXPLANATION:

The code example below consists of one table definition and two
programs.

The first program is shut.p. This is a daemon that needs to be
executed in batch mode inside the Server using a self-service client
connection. Shut.p will poll a record from the table 'shut'.
Whenever there is a change in the field shut_status to true, it will
shut the process with the number contained in shut_id.

The second program is shutr.p and it must run on the client side.
Using the VST table _connect, it detects the users that are connected
remotely and lists them in a browser. To disconnect a user, select
the user and press the "shut" button.

SOLUTION:

The five steps to implement this remote proshut are as follows:

1) If you are using Version 8 of Progress you need to enable the VST
using: proutil sports -C enablevst

2) Load the following table definition for the 'shut' table:

UPDATE DATABASE "?"

ADD TABLE "Shut"
AREA "Schema Area"
DUMP-NAME "shut"

ADD FIELD "shut_status" OF "Shut" AS logical
DESCRIPTION "When changed to ""yes"" a daemon process will proceed
to disconnect the remote user."
FORMAT "yes/no"
INITIAL "no"
LABEL "Shut user ? (yes/no)"
POSITION 2
SQL-WIDTH 1
ORDER 10

ADD FIELD "shut_id" OF "Shut" AS integer
DESCRIPTION "Id of the user to be disconnected."
FORMAT "->,>>>,>>9"
INITIAL "0"
POSITION 4
SQL-WIDTH 4
ORDER 20

.
PSC
cpstream=ISO8859-1
.
0000000523


3) Load the following record (shut.d) into the 'shut' table:

no 0
.
PSC
filename=Shut
records=0000000000001
ldbname=Shut
timestamp=2001/06/29-13:20:32
numformat=44,46
dateformat=mdy-1950
map=NO-MAP
cpstream=ISO8859-1
.
0000000009


4) At the Server, execute in batch mode the following program
using the command: mbpro sports -p shut.p

/* shut.p */
/* Daemon that will monitor the table SHUT */
/* This table must be loaded in the Database you want to control */

REPEAT:
FIND FIRST shut NO-LOCK.
IF shut_status THEN
DO:
OS-COMMAND SILENT VALUE("proshut sports -C disconnect " +
trim(string(shut_id,">>9"))).
FIND FIRST shut SHARE-LOCK.
ASSIGN shut_status=NO shut_id=0.
RELEASE shut.
END.
PAUSE 1.
END.


5) On the client side, execute the following program:

/* shutr.p */
/* This program will run on the client side and will browse a Promon
like a user list */
/* If you press the shut button it will disconnect the selected user
and exit*/

def var shut_w as widget-handle no-undo.
def button but_shut label "Shut User".


DEFINE FRAME shut_f WITH 1 DOWN
NO-BOX KEEP-TAB-ORDER OVERLAY
SIDE-LABELS NO-UNDERLINE THREE-D AT COL 1 ROW 1
SIZE 120 BY 14.50.


define query shut_q for _CONNECT.
define browse shut_b query shut_q
display _CONNECT-usr _CONNECT-NAME _CONNECT-type _CONNECT-wait
_CONNECT-wait1 _CONNECT-transID _CONNECT-pid _CONNECT-server
_CONNECT-time
with 15 down.


def button but_exit label "Exit".

form shut_b
but_exit AT 1
but_shut AT 105
with frame shut_f
cancel-button but_exit.

ON CHOOSE OF but_shut
DO:
FIND FIRST shut.
ASSIGN shut_status = YES shut_id = _connect._CONNECT-usr.
RELEASE shut.
QUIT.
END.

create window shut_w
ASSIGN
HEIGHT = 14.50
WIDTH = 120
STATUS-AREA = no
MESSAGE-AREA = no.


DO:
FIND FIRST shut.
ASSIGN shut_status = NO shut_id = 0.
RELEASE shut.
END.

open query shut_q FOR EACH _CONNECT WHERE _CONNECT-type = "REMC".
view frame shut_f in window shut_w.
enable all with frame shut_f in window shut_w.

apply "cursor-down" to shut_b.

wait-for window-close of shut_w or choose of but_exit.
delete widget shut_w.
QUIT.


References to Written Documentation:

Progress System Administration Reference

Progress Knowledge Base Solution 19935, "How to Control User Sessions
Using VST"

/dmi

Аватара пользователя
Arelav
Администратор
Сообщения: 1881
Зарегистрирован: 25 мар 2005, 17:05
Откуда: Progress Technologies
Контактная информация:

Сообщение Arelav » 01 ноя 2006, 11:54

В promon вижу двух пользователей, лочаших одну и ту же запись одной таблицы.
Результат, такой же как описано предыдущими аторами.
Проблема заключается в том, что есть ~10000 исходников.
Оба логина виртуальные, т.е не привязаны к конкретным людям.
Этих логинов могут быть по несколько штук. Т.е. я не знаю что конкретно работает, какая программа.
Можно ли как найти ее по тем данным, что есть в promon?

Аватара пользователя
George
Старожил
Сообщения: 2871
Зарегистрирован: 12 май 2004, 17:03
Откуда: Питер

Re: re:блокировка записи

Сообщение George » 01 ноя 2006, 16:14

Пробовал вот такое:

find first sign no-lock no-error.

find first _file where _file._file-name = "sign" no-lock no-error.

find first _lock where _lock._lock-recid = integer(recid(sign)) and _lock._lock-table = _file._file-num and _lock._lock-flag = "x" no-lock no-error.

Так вот, зря я писал, что последний FIND "бесконечный". Не бесконечный он, но!... На реальной работающей базе это заняло 3966 секунд!!! :eek: На локальной "пустышке" - около двух минут (и это при пустой таблице блокировок!), что тоже не сахар. В общем, тут VST не помогают :cry:

Проблема с _Lock VST состоит в том, что каждая отдельная запись читается в -lkhash раз медленнее, чем любая другая VST. Значение по-умолчанию параметра -lkhash примерно равно -L / 8. На рабочей базе, где -L задано очень большим этот "фактор замедления" становится просто безумным. При этом процесс, читающий _Lock, будет загружать процессор по полной.

Ситуацию можно несколько облегчить, если читать минимальное число записей в таблице _Lock. При этом надо учитывать, что у всех VST таблиц нет настоящего индекса. Второй момент специфичен для таблицы _Lock: все "заполненные" записи идут первыми.
На этом основании пишем:

Код: Выделить всё

assign vLockFlag = "".
for each _lock WHILE _lock._lock-recid ne ?:
  if _lock._lock-recid ne integer(recid(sign))
  or _lock._lock-table ne _file._file-num
  then next.

  assign vLockFlag = _lock._lock-flag.
  leave.
end.


Если общее число локированных записей небольшое, то код будет работать с приемлемой скоростью.

Аватара пользователя
George
Старожил
Сообщения: 2871
Зарегистрирован: 12 май 2004, 17:03
Откуда: Питер

Re: re:блокировка записи

Сообщение George » 01 ноя 2006, 16:24

new писал(а):Возможно ли снять блокировку записи (др. пользователя ) програмно.

Нет.

Но если пробный CAN-FIND с SHARE запускать не из транзакции, то, как уже сказал dmi, если замок сумеет повесится, то тут же он и снимется.

Но если дальнейшая цель - залокировать запись, то, по-моему, запускать CAN-FIND как пробный шар не нужно. Здесь подойдет FIND NO-WAIT.

А к чтению таблицы _Lock нужно прибегать, IMHO, если очень нужно знать какая :lol: пользователь залокировал запись.

Аватара пользователя
George
Старожил
Сообщения: 2871
Зарегистрирован: 12 май 2004, 17:03
Откуда: Питер

Сообщение George » 01 ноя 2006, 16:41

Валерий писал(а):В promon вижу двух пользователей, лочаших одну и ту же запись одной таблицы.

Ну лочит-то, допустим, только один пользователь. Второй (или другие) стоит в очереди на запись.
Можно ли как найти ее по тем данным, что есть в promon?

К великому сожалению promon мало, что показывает про действия клиентов.

Поиск "злолочных" программ можно организовать так:
Всех клиентов запускать с -clientlog mylog.lg -logginglevel 4 -logentrytypes 2.

В фоновом режиме для базы запускается promon, собирающий статистику по локировкам:
Status: Lock Table
Status: Blocked Clients

Пример скрипта:
ftp.progress-tech.ru/incoming/George/Scripts/dbmon.sh
Надо только выбросить из него сбор лишней информации.

Либо в фоновом процессе отслеживать пользователей, создающих наибольшее количество одновременных локировок - "диагональный чёс" таблицы _UserLock.

Ну а далее нудно сопоставлять времена "событий" с временами вызовов процедур на конкретном клиенте.

bulklodd
Старожил
Сообщения: 448
Зарегистрирован: 27 июл 2001, 03:00
Откуда: Москва
Контактная информация:

Re: блокировка записи

Сообщение bulklodd » 18 дек 2014, 18:29

Продолжу тему локировки следующей задачей

Есть следующий код, в результате выполнения которого ОЧЕНЬ часто в RUN wholocks.p (RECID(bloan) приходит ?, т.е. запись которая была LOCKED при поиске с NO-LOCK не находится. Оба запроса абсолютно одинаковы, орфографических ошибок нет (вроде). Как это возможно? Объяснение, что запись была удалена между двумя поисками, не подходит.

Код: Выделить всё

     5612            FIND FIRST bloan WHERE bloan.class-code       EQ "loan-rent-dop"
     5613                               AND bloan.parent-contract  EQ loan.contract
     5614                               AND bloan.parent-cont-code EQ loan.cont-code
     5615                               AND bloan.contract         EQ loan.contract
     5616                               AND bloan.doc-ref          EQ loan.doc-ref + " 1"
     5617               EXCLUSIVE-LOCK NO-WAIT NO-ERROR.
     5618
     5619            IF NOT AVAILABLE bloan THEN
     5620            DO:
     5621
     5622               IF LOCKED bloan THEN
     5623               DO:
     5624                  FIND FIRST bloan WHERE bloan.class-code       EQ "loan-rent-dop"
     5625                                     AND bloan.parent-contract  EQ loan.contract
     5626                                     AND bloan.parent-cont-code EQ loan.cont-code
     5627                                     AND bloan.contract         EQ loan.contract
     5628                                     AND bloan.doc-ref          EQ loan.doc-ref + " 1"
     5629                     NO-LOCK NO-ERROR.
     5630   
     5631                  RUN wholocks.p (RECID(bloan),"").

idl
Старожил
Сообщения: 94
Зарегистрирован: 21 май 2009, 15:41

Re: блокировка записи

Сообщение idl » 19 дек 2014, 16:35

Вроде не о том, но рядом

Код: Выделить всё

http://knowledgebase.progress.com/articles/Article/000044741